2014-01-02 17:21:01
来 源
IT技术网
Nginx
本文介绍Nginx服务器出现502504错误的解决办法,希望对于初学Nginx服务器相关的朋友有帮助,更多Nginx安装、配置、报错处理等资源请本站内搜索。。

Nginx 502 Bad Gateway的含义是请求的PHP-CGI已经执行,但是由于某种原因(一般是读取资源的问题)没有执行完毕而导致PHP-CGI进程终止。

错误排查:

1 、查看fastcgi进程是否启动

2、检查系统中fastcgi进程的运行情况

当系统中fastcGI进程数不够用、php执行时间长、或者是php-cgi进程死掉也可能造成502错误

首先查看系统中开启fastcGI的进程数

ps aux | grep "php-cgi" | wc -l

查看有多少php-cgi来处理请求

netstat -anpo | grep "php-cgi" | grep -v "grep" | wc -l

如果处理请求的进程数接近开启的进程数说明worker进程数配置太少,需要修改php-fpm.conf来增大php的进程数

3、fastcGI执行时间过长

可以根据实际情况调高nginx.conf中的以下参数:

fastcgi_connect_timeout 300;

fastcgi_send_timeout 300;

fastcgi_read_timeout 300;

增加了fastcgi的相应请求时间。但是我在实际中碰到了这个问题,设置到500,还是会出现,只是比我设置120的时候要少一些。后来发现主要是在一些post或者数据库操作的时候出现这种情况,静态页面是不会出现的。

反复的查问题,调试,也加大了CGI的进程数。

128

256再加上去可能会变得很慢。占用内存大了。

在php-fpm.conf设置中还有一项,可能当时没注意到,无意中改了这个值。

request_terminate_timeout

这个值是max_execution_time,就是fast-cgi的执行脚本时间。

0s

0s为关闭,就是无限执行下去。(当时装的时候没仔细看就改了一个数字)

发现,问题解决了,执行很长时间也不会出错了

优化fastcgi中,还可以改改这个值5s 。看看效果

4、头部太大

nginx和apache一样,有前段缓冲限制,可以调整缓冲参数

fastcgi_buffer_size 32k;

fastcgi_buffers 8 32k;

如果你使用的是nginx的负载均衡Proxying,调整

proxy_buffer_size 16k;

proxy_buffers 4 16k;

5、https转发配置错误

正确的配置方法

server_name www.mydomain.com;

location /myproj/repos {

set $fixed_destination $http_destination;

if ( $http_destination ~* ^https(.*)$ )

{

set $fixed_destination http$1;

}

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header Destination $fixed_destination;

proxy_pass http://subversion_hosts;

}

6、将nginx的error log打开,发现”pstream sent too big header while reading response header from upstream”这样的错误提示,查阅了一下资料,大意是nginx缓冲区有一个bug造成的,我们网站的页面消耗占用缓冲区可能过大。参考老外写的修 改办法增加了缓冲区容量大小设置,502问题彻底解决,后来系统管理员又对参数做了调整只保留了2个设置参数:client head buffer,fastcgi buffer size。

http://blog.rackcorp.com/?p=14

7、一台服务器上运行着nginx php(fpm) xcache,访问量日均 300W pv左右

最近经常会出现这样的情况: php页面打开很慢,cpu使用率突然降至很低,系统负载突然升至很高,查看网卡的流量,也会发现突然降到了很低。这种情况只持续数秒钟就恢复了

检查php-fpm的日志文件发现了一些线索

Sep 30 08:32:23.289973 [NOTICE] fpm_unix_init_main(), line 271: getrlimit(nofile): max:51200, cur:51200

Sep 30 08:32:23.290212 [NOTICE] fpm_sockets_init_main(), line 371: using inherited socket fd=10,

Sep 30 08:32:23.290342 [NOTICE] fpm_event_init_main(), line 109: libevent: using epoll

Sep 30 08:32:23.296426 [NOTICE] fpm_init(), line 47: fpm is running, pid 30587

在这几句的前面,是1000多行的关闭children和开启children的日志?

原来,php-fpm有一个参数 max_requests ,该参数指明了,每个children最多处理多少个请求后便会被关闭,默认的设置是500。因为php是把请求轮询给每个children,在大流量 下,每个childre到达max_requests所用的时间都差不多,这样就造成所有的children基本上在同一时间被关闭。

在这期间,nginx无法将php文件转交给php-fpm处理,所以cpu会降至很低(不用处理php,更不用执行sql),而负载会升至很高(关闭和开启children、nginx等待php-fpm),网卡流量也降至很低(nginx无法生成数据传输给客户端)

解决问题很简单,增加children的数量,并且将 max_requests 设置未 0 或者一个比较大的值,重启php-fpm

Nginx 504 Gateway Time-out的含义是所请求的网关没有请求到,简单来说就是没有请求到可以执行的PHP-CGI。

解决这两个问题其实是需要综合思考的,一般来说Nginx 502 Bad Gateway和php-fpm.conf的设置有关,而Nginx 504 Gateway Time-out则是与nginx.conf的设置有关。

而正确的设置需要考虑服务器自身的性能和访客的数量等多重因素。

fastcgi_connect_timeout 300s;

fastcgi_send_timeout 300s;

fastcgi_read_timeout 300s;

fastcgi_buffer_size 128k;

fastcgi_buffers 8 128k;#8 128

fastcgi_busy_buffers_size 256k;

fastcgi_temp_file_write_size 256k;

fastcgi_intercept_errors on;

这里最主要的设置是前三条,即

fastcgi_connect_timeout 300s;

fastcgi_send_timeout 300s;

fastcgi_read_timeout 300s;

这里规定了PHP-CGI的连接、发送和读取的时间,300秒足够用了,因此我的服务器很少出现504 Gateway Time-out这个错误。最关键的是php-fpm.conf的设置,这个会直接导致502 Bad Gateway和504 Gateway Time-out。

下面我们来仔细分析一下php-fpm.conf几个重要的参数:

php-fpm.conf有两个至关重要的参数,一个是”max_children”,另一个是”request_terminate_timeout”

我的两个设置的值一个是”40″,一个是”900″,但是这个值不是通用的,而是需要自己计算的。

计算的方式如下:

如果你的服务器性能足够好,且宽带资源足够充足,PHP脚本没有系循环或BUG的话你可以直接将”request_terminate_timeout”设置成0s。0s的含义是让PHP-CGI一直执行下去而没有时间限制。而如果你做不到这一点,也就是说你的PHP-CGI可能出现某个BUG,或者你的宽带不够充足或者其他的原因导致你的PHP-CGI能够假死那么就建议你给”request_terminate_timeout”赋一个值,这个值可以根据你服务器的性能进行设定。一般来说性能越好你可以设置越高,20分钟-30分钟都可以。由于我的服务器PHP脚本需要长时间运行,有的可能会超过10分钟因此我设置了900秒,这样不会导致PHP-CGI死掉而出现502 Bad gateway这个错误。

而”max_children”这个值又是怎么计算出来的呢?这个值原则上是越大越好,php-cgi的进程多了就会处理的很快,排队的请求就会很少。设置”max_children”也需要根据服务器的性能进行设定,一般来说一台服务器正常情况下每一个php-cgi所耗费的内存在20M左右,因此我的”max_children”我设置成40个,20M*40=800M也就是说在峰值的时候所有PHP-CGI所耗内存在800M以内,低于我的有效内存1Gb。而如果我的”max_children”设置的较小,比如5-10个,那么php-cgi就会“很累”,处理速度也很慢,等待的时间也较长。如果长时间没有得到处理的请求就会出现504 Gateway Time-out这个错误,而正在处理的很累的那几个php-cgi如果遇到了问题就会出现502 Bad gateway这个错误。

声明: 此文观点不代表本站立场;转载须要保留原文链接;版权疑问请联系我们。