网络架构如下:
nginx1
| rewrite
nginx2
| pass
resin1
nginx1是在192.168.1.1上
nginx2跟resin1是在192.168.1.2上
首先,访问nginx1,由nginx1 rewrite到nginx2,nginx2直接pass到resin1,整个过程是POST形式。至于为什么要用两层nginx,这当然是有原因的。
于是乎,快速制定了几个测试案例:
1,两种访问方式:GET,POST
GET URL带参数,没有问题。
POST 有问题。
让网络同事检查,处理这个location并没有做什么特殊的POST处理。——!
2,访问nginx1时,直接pass到resin1,跳过nginx2
问题依旧。
3,去掉nginx1,访问nginx2,直接pass到resin1
有数据的。
4,直接访问resin1
是有数据的。
为什么nginx1传递不了post数据,而nginx2可以,问题肯定出在nginx1的配置上。
经过一番折腾,终于找到了问题关键:
nginx1中,配置了一个全的post处理
rewrite .* /post.php last;
}
在nginx的access.log中存在大量的400错误,并以每天几百M的速度增加,占用大量空间。
116.236.228.180 - - [15/Dec/2010:11:00:15 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:15 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:15 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:15 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:15 +0800] "-" 400 0 "-" "-"
119.97.196.7 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
119.97.196.7 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
219.243.95.197 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
116.236.228.180 - - [15/Dec/2010:11:00:16 +0800] "-" 400 0 "-" "-"
网上很多资料说是HTTP头/Cookie过大引起的,可以修改nginx.conf中两参数来修正.
large_client_header_buffers 4 32k;
修改后
large_client_header_buffers 4 64k;
没有效果,即便把nginx0.7.62升到最新的0.8.54也是无果。
在官方论坛中,nginx作者提到空主机头不会返回自定义的状态码,而是返回400错误。参见:http://forum.nginx.org/read.php?2,9695,11560
最后修正如下,改为原先的值:
large_client_header_buffers 4 32k;
关闭默认主机的日志记录,即可解决问题:
listen *:80 default;
server_name _;
return 444;
access_log off;
}
问题:
nginx +fpm,nginx无法探知 php输出内容长度,默认用Tranfer-Encoding:chunked编码 输出。
解决:
对于一些客户端,需要自己解析http协议的,一般不支持chunked解码,这时,可以在php输出里 加一个header('Content-Length: length' )
可以覆盖nginx的默认行为,计算内容长度可以用php自带的strlen 方法。