nginx+php-fpm.sock时504,502错误解决办法

nginx+php-fpm.sock时504,502错误解决办法

环境:
CentOS 7.1 x64
nginx-1.8.0
php-5.6.17
nginx和php通信采用的是unix socket机制

小记:
http://nginx.org/en/docs/stream/ngx_stream_core_module.html  nginx-1.9.0开始支持tcp的反向代理,编译时需要加上--with-stream参数


504
出现错误的前因
在phpMyAdmin中执行了一段非常耗时的查询语句,不一会功夫,phpMyAdmin就报如下错误
nginx+php-fpm.sock时504,502错误解决办法
nginx日志

2016/04/02 22:28:56 [error] 15308#0: *53 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.130.1, server: ssl.example.com, request: "POST /phpMyAdmin/import.php HTTP/1.1", upstream: "fastcgi://unix:/dev/shm/php-fpm.sock", host: "192.168.130.254", referrer: "https://192.168.130.254/phpMyAdmin/db_sql.php?db=isfdb&token=b9cf017794df498e0cb52518b8021c82"

2016/04/02 22:33:00 [error] 15305#0: *71 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.130.1, server: ssl.example.com, request: "GET /phpMyAdmin/ HTTP/1.1", upstream: "fastcgi://unix:/dev/shm/php-fpm.sock", host: "192.168.130.254"

此里所有同php解析的动态内容全部无法打开,想临时解决,重启php-fpm即可(注意:重启nginx无效),但只治得了一时,于时开始查找解决方案

解决办法

        location ~ \.php$ {

        fastcgi_connect_timeout      180;

        fastcgi_read_timeout         600;

        fastcgi_send_timeout         600;

        fastcgi_pass unix:/tmp/php-fpm.sock;

        fastcgi_index index.php;

        include fastcgi.conf;

 

       

调高上面标红的3个值后,主要是read和send两项(默认Nginx超时为60),完美地解决了504错误。
并且可以配置在http,server级别,也可以配置在location级别。

 

factcgi_connect_{read|send|timeout}是对fastcgi_pass生效
proxy_connect_{read|send|timeout|是对proxy_pass生效


502

的确,504是解决了,但运行一段时间后,又报了502错误

nginx+php-fpm.sock时504,502错误解决办法

nginx日志

2016/04/02 23:24:55 [error] 18748#0: *35 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 192.168.130.1, server: ssl.example.com, request: "POST /phpMyAdmin/import.php HTTP/1.1", upstream: "fastcgi://unix:/dev/shm/php-fpm.sock:", host: "192.168.130.254", referrer: "https://192.168.130.254/phpMyAdmin/db_sql.php?db=isfdb&token=231148330c40cfa09b03d52ccf49f38a"


php-fpm日志

[02-Apr-2016 23:24:55] WARNING: [pool www] child 18822, script '/usr/local/nginx/html/phpMyAdmin/import.php' (request: "POST /phpMyAdmin/import.php") execution timed out (340.677871 sec), terminating

[02-Apr-2016 23:24:55] WARNING: [pool www] child 18822 exited on signal 15 (SIGTERM) after 396.757450 seconds from start

 

[02-Apr-2016 23:24:55] NOTICE: [pool www] child 19164 started


从日志上可以看到, 23:24:55的时,php-fpm的子进程18822因为等待了340.677871秒后被强行终止了并重新生成了一个新的子进程19164

但因为自动生成了新子进程,php网页还是可以正常访问的,只是该查询任务被终止了。


解决办法

php.ini中的max_execution_time值
php-fpm.conf中的request_terminate_timeout值

这两项都是用来配置PHP脚本的最大执行时间。超时时php-fpm会终止脚本的执行,同时还会终止执行脚本的Worker进程。
如上,php-fpm child 18822被terminate后重新生成了新的Worker进程19164,所以nginx发现与自己通信的连接断了,就自然会返回502错误给客户端。客户端需再次发起请求重新建立新的连接,表象是刷新下浏览器即重新发起请求
所以只需将这两项的值适当调大,让PHP脚本不会因为执行时间长而被终止从而与nginx激活连接丢失。

request_terminate_timeout优先级高于max_execution_time,不想改全局的php.ini,只改php-fpm的配置就可以了。这里暂且调到600秒

request_terminate_timeout = 600




补充:
nginx也要注意upstream模块中max_fail和fail_timeout。有时nginx与后端服务器(Tomcat、FastCGI)的通信只是偶然断掉,但max_fail设置太小,那么在接下来的fail_timeout时间内,nginx都会认为后端服务器无响应,都会返回502错误。
所以可以将max_fail调大一些,将fail_timeout调小一些
posted @ 2016-04-02 22:04  李庆喜  阅读(838)  评论(0编辑  收藏  举报