/ 中存储网

配置Nginx前端 + Apache后端服务器环境

2013-12-27 14:27:01 来源:ITJS.CN

说明:

nginx处理静态内容是把好手,apache虽然占用内存多了点,性能上稍逊,但一直比较稳健。倒是nginx的FastCGI有时候会出现502 Bad Gateway错误。一个可选的方法是nginx做前端代理,处理静态内容,动态请求统统转发给后端apache。

本文就是实现Nginx作为前端,apache作为后端。当用户访问的是80端口的nginx,然后nginx将静态内容留给自己,其余的转发给非80端口的apache,apache处理完毕后再回传给nginx。例如这里我分别访问www.test.com/a.html,www.test.com/info.php。nginx因为做前面,nginx的访问日志应该都有a.html,info.php的记录;而apache作为后端,只处理php请求,应该只有info.php的访问记录。

实现:

1.修改nginx配置文件,将php动态请求转发给apache

# cat /usr/local/nginx/conf/vhosts/test.conf

server

{

listen       80;

server_name www.test.com test.com;

index index.html index.htm index.php default.html default.htm default.php;

root  /home/www/data/test;

access_log  /usr/local/nginx/logs/test-access.log;

nginx找不到文件时,转发请求给后端Apache

error_page 404 @proxy;

这是原来lnmp时,nginx自己将php请求提交到127.0.0.1:9000。现在由apache来处理,因此注释掉这段。

#location ~ .*.(php|php5)?$

#{

fastcgi_pass  127.0.0.1:9000;

fastcgi_index index.php;

include fastcgi.conf;

#}

location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$

{

expires      30d;

}

location ~ .*.(js|css)?$

{

expires      12h;

}

动态文件.php请求转发给后端Apache

location ~ .php$ {

# 向后端服务器发起请求时添加指定的header头信息

proxy_set_header Host $http_host;

# 向后端服务器发送真实 IP

proxy_set_header X-Real-IP $remote_addr;

# 让后端如php能直接通过变量获取真实IP

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_pass   http://127.0.0.1:8080;

}

nginx找不到文件时,转发请求给后端Apache

location @proxy {

proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_pass http://127.0.0.1:8080;

}

}

然后只要开启nginx监听80端口,apache监听8080端口,开启php,就可以了。这边,我同时开启nginx,apache的访问日志。当我访问www.test.com/a.html,www.test.com/info.php时,nginx记录下了所有a.html,info.html的访问请求。

nginx访问日志

192.168.45.30 - - [19/Jun/2013:14:41:06 +0800] "GET /a.html HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:06 +0800] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:08 +0800] "GET /info.php HTTP/1.1" 200 10518 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:08 +0800] "GET /info.php?=PHPE9568F35-D428-11d2-A769-00AA001ACF42 HTTP/1.1" 200 2158 "http://www.test.com/info.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:08 +0800] "GET /info.php?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 HTTP/1.1" 200 2536 "http://www.test.com/info.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:08 +0800] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:09 +0800] "GET /info.php HTTP/1.1" 200 10518 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

当我访问www.test.com/a.html,www.test.com/info.php时,apache只记录了info.html的访问请求。说明nginx将php请求转发给了apache。这里可以看到来源都是127.0.0.1。而不是真实的来源ip。

apache访问日志

127.0.0.1 - - [19/Jun/2013:11:04:16 +0800] "GET /favicon.ico HTTP/1.0" 404 209

127.0.0.1 - - [19/Jun/2013:11:04:23 +0800] "GET /favicon.ico HTTP/1.0" 404 209

127.0.0.1 - - [19/Jun/2013:11:04:31 +0800] "GET /favicon.ico HTTP/1.0" 404 209

127.0.0.1 - - [19/Jun/2013:11:04:34 +0800] "GET /favicon.ico HTTP/1.0" 404 209

127.0.0.1 - - [19/Jun/2013:11:04:39 +0800] "GET /favicon.ico HTTP/1.0" 404 209

127.0.0.1 - - [19/Jun/2013:11:05:09 +0800] "GET /favicon.ico HTTP/1.0" 404 209

127.0.0.1 - - [19/Jun/2013:11:05:18 +0800] "GET /favicon.ico HTTP/1.0" 404 209

127.0.0.1 - - [19/Jun/2013:11:05:24 +0800] "GET /info.php HTTP/1.0" 200 55447

127.0.0.1 - - [19/Jun/2013:11:05:24 +0800] "GET /info.php?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 HTTP/1.0" 200 2524

127.0.0.1 - - [19/Jun/2013:11:05:24 +0800] "GET /info.php?=PHPE9568F35-D428-11d2-A769-00AA001ACF42 HTTP/1.0" 200 2146

127.0.0.1 - - [19/Jun/2013:11:05:24 +0800] "GET /favicon.ico HTTP/1.0" 404 209

2.apache添加mod_rpaf, 获取nginx转发过来的真实IP

mod_rpaf模块不是必须安装,除非你需要开启apache日志,但有多此一举之嫌,因为已经有nginx日志了,再开apache日志话就出现重复了。

Apache rpaf模块作用是获取Nginx转发过来的真实IP,否则在Apache日子中来访IP全部为127.0.0.1。

# wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz

# tar zxvf mod_rpaf-0.6.tar.gz

# cd mod_rpaf-0.6

# /usr/local/www/apache/bin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

安装过程中,若出现error: 'conn_rec' has no member named 'remote_ip,请参考附录1.mod_rpaf-2.0.c error: 'conn_rec' has no member named 'remote_ip

 

# vim /usr/local/apache/conf/httpd.conf  //在LoadModule后添加以下内容

LoadModule rpaf_module modules/mod_rpaf-2.0.so

RPAFenable On

RPAFproxy_ips 127.0.0.1

RPAFsethostname On

RPAFheader X-Forwarded-For

下面是apache添加了mod_rpaf模块后,apache的访问日志

192.168.45.30 - - [19/Jun/2013:14:41:09 +0800] "GET /info.php?=PHPE9568F35-D428-11d2-A769-00AA001ACF42 HTTP/1.1" 200 2158 "http://www.test.com/info.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:09 +0800] "GET /info.php?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 HTTP/1.1" 200 2536 "http://www.test.com/info.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:09 +0800] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:09 +0800] "GET /info.php HTTP/1.1" 200 10520 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

192.168.45.30 - - [19/Jun/2013:14:41:09 +0800] "GET /info.php?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 HTTP/1.1" 200 2536 "http://www.test.com/info.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

附录:

附录1.mod_rpaf-2.0.c error: 'conn_rec' has no member named 'remote_ip

mod_rpaf-2.0.c: In function 'rpaf_cleanup':

mod_rpaf-2.0.c:150: error: 'conn_rec' has no member named 'remote_ip'

mod_rpaf-2.0.c:151: error: 'conn_rec' has no member named 'remote_addr'

mod_rpaf-2.0.c:151: warning: implicit declaration of function 'inet_addr'

mod_rpaf-2.0.c:151: error: 'conn_rec' has no member named 'remote_ip'

mod_rpaf-2.0.c: In function 'change_remote_ip':

mod_rpaf-2.0.c:164: error: 'conn_rec' has no member named 'remote_ip'

mod_rpaf-2.0.c:183: error: 'conn_rec' has no member named 'remote_ip'

mod_rpaf-2.0.c:186: error: 'conn_rec' has no member named 'remote_ip'

mod_rpaf-2.0.c:187: error: 'conn_rec' has no member named 'remote_addr'

mod_rpaf-2.0.c:187: error: 'conn_rec' has no member named 'remote_ip'

apxs:Error: Command failed with rc=65536

只要将mod_rpaf-2.0.c的150、151、164、183、186、187这几行的remote_ip修改成client_ip,remote_addr修改成client_addr,

然后再/usr/local/www/apache/bin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c即可