Nginx中502和504错误详解

小强性能测试2016年11月6号开课。

小强python(接口+selenium+Appium)全栈自动化测试班2017年2月开课

报名QQ:2083503238、1684129674、480934277(所有学员享受终生免费不限次数重学的福利!)

介绍见http://xqtesting.sxl.cn

在使用Nginx时,经常会碰到502 Bad Gateway和504 Gateway Time-out错误,下面以Nginx+PHP-FPM来分析下这两种常见错误的原因和解决方案。

1.502 Bad Gateway错误

在php.ini和php-fpm.conf中分别有这样两个配置项:max_execution_time和request_terminate_timeout。

这两项都是用来配置一个PHP脚本的最大执行时间的。当超过这个时间时,PHP-FPM不只会终止脚本的执行,还会终止执行脚本的Worker进程。所以Nginx会发现与自己通信的连接断掉了,就会返回给客户端502错误。

以PHP-FPM的request_terminate_timeout=30秒时为例,报502 Bad Gateway错误的具体信息如下:

1)Nginx错误访问日志:

2013/09/19 01:09:00 [error] 27600#0: *78887 recv() failed (104: Connection reset by peer) while reading response header from upstream,

client: 192.168.1.101, server: test.com, request: "POST /index.php HTTP/1.1", upstream: "fastcgi://unix:/dev/shm/php-fcgi.sock:",

host: "test.com", referrer: "http://test.com/index.php"

2)PHP-FPM报错日志:

WARNING:  child 25708 exited on signal 15 (SIGTERM) after 21008.883410 seconds from start

所以只需将这两项的值调大一些就可以让PHP脚本不会因为执行时间长而被终止了。request_terminate_timeout可以覆盖max_execution_time,所以如果不想改全局的php.ini,那只改PHP-FPM的配置就可以了。

解决办法是request_terminate_timeout设置为10s或者一个合理的值,或者给file_get_contents加一个超时参数。

$ctx= stream_context_create(array(

'http'=>array(

'timeout'=> 10//设置一个超时时间,单位为秒

)

)

);

file_get_contents($str, 0,$ctx);

此外要注意的是Nginx的upstream模块中的max_fail和fail_timeout两项。有时Nginx与上游服务器(如Tomcat、FastCGI)的通信只是偶然断掉了,但max_fail如果设置的比较小的话,那么在接下来的fail_timeout时间内,Nginx都会认为上游服务器挂掉了,都会返回502错误。所以可以将max_fail调大一些,将fail_timeout调小一些。

2、max_requests参数配置不当,可能会引起间歇性502错误:

pm.max_requests = 1000

#设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.

这段配置的意思是,当一个 PHP-CGI 进程处理的请求数累积到 500 个后,自动重启该进程。

但是为什么要重启进程呢?

一般在项目中,我们多多少少都会用到一些 PHP 的第三方库,这些第三方库经常存在内存泄漏问题,如果不定期重启 PHP-CGI 进程,势必造成内存使用量不断增长。因此 PHP-FPM 作为 PHP-CGI 的管理器,提供了这么一项监控功能,对请求达到指定次数的 PHP-CGI 进程进行重启,保证内存使用量不增长。

正是因为这个机制,在高并发的站点中,经常导致 502 错误,我猜测原因是 PHP-FPM 对从 NGINX 过来的请求队列没处理好。不过我目前用的还是 PHP 5.3.2,不知道在 PHP 5.3.3 中是否还存在这个问题。

目前我们的解决方法是,把这个值尽量设置大些,尽可能减少 PHP-CGI 重新 SPAWN 的次数,同时也能提高总体性能。在我们自己实际的生产环境中发现,内存泄漏并不明显,因此我们将这个值设置得非常大(204800)。大家要根据自己的实际情况设置这个值,不能盲目地加大。

话说回来,这套机制目的只为保证 PHP-CGI 不过分地占用内存,为何不通过检测内存的方式来处理呢?我非常认同高春辉所说的,通过设置进程的峰值内在占用量来重启 PHP-CGI 进程,会是更好的一个解决方案。

3.504 Gateway Time-out错误

PHP-FPM设置的脚本最大执行时间已经够长了,但执行耗时PHP脚本时,发现Nginx报错从502变为504了。这是为什么呢?

因为我们修改的只是PHP的配置,Nginx中也有关于与上游服务器通信超时时间的配置factcgi_connect/read/send_timeout。

以Nginx超时时间为90秒,PHP-FPM超时时间为300秒为例,报504 Gateway Timeout错误时的Nginx错误访问日志如下:

2013/09/19 00:55:51 [error] 27600#0: *78877 upstream timed out (110: Connection timed out) while reading response header from upstream,

client: 192.168.1.101, server: test.com, request: "POST /index.php HTTP/1.1", upstream: "fastcgi://unix:/dev/shm/php-fcgi.sock:",

host: "test.com", referrer: "http://test.com/index.php"

调高这三项的值(主要是read和send两项,默认不配置的话Nginx会将超时时间设为60秒)之后,504错误也解决了。

而且这三项配置可以配置在http、server级别,也可以配置在location级别。担心影响其他应用的话,就配置在自己应用的location中吧。要注意的是factcgi_connect/read/send_timeout是对FastCGI生效的,而proxy_connect/read/send_timeout是对proxy_pass生效的。

配置举例:

location ~ \.php$ {

root                   /home/cdai/test.com;

include                 fastcgi_params;

fastcgi_connect_timeout      180;

fastcgi_read_timeout        600;

fastcgi_send_timeout        600;

fastcgi_pass              unix:/dev/shm/php-fcgi.sock;

fastcgi_index             index.php;

fastcgi_param     SCRIPT_FILENAME/home/cdai/test.com$fastcgi_script_name;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,265评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,274评论 1 288
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,087评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,479评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,782评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,218评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,594评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,316评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,955评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,274评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,803评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,177评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,732评论 3 229
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,953评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,687评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,263评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,189评论 2 258

推荐阅读更多精彩内容