背景:
经常遇到502 bad gateway,504 gateway timeout(其实很少500, php fatal error也是200,状态码只是一个约定的东西,大部分web框架都会将程序错误改成404并改成一个死撑装逼的页面(header(“HTTP/1.0 404 Not Found”);),所以看错误信息才是王道)
502:
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
504:
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"
解析
502的情况是 php 进程挂了,nginx 失去通信
504 gateway timeout就是nginx 等不到上游信息,相关参数是factcgi_connect/read/send_timeout
nginx 和 php都可以设置记录错误日志(任何程序都必须要有记录日志功能)
nginx_error.log
php_errors.log … 框架自己写日志跟php自带的写日志不冲突
php参数:
php.ini (全局参数)
max_execution_time 会被request_terminate_timeout 覆盖 (不同的php运行模式使用不用的配置文件,所以摸清php的运行机制才是王道)
所以set_time_limit 不生效,因为它设置的是max_execution_time (php5.3 不再有安全模式)
php-fpm
(max_children, pool 进程是共用的,一个请求一个进程,如果没有足够的进程去处理请求,就会造成nginx等待,时间太长也会导致nginx报错)
request_terminate_timeout 超过这个时间php-fpm 就会杀死php子进程
nginx 失去通信就会502
Fix
将request_terminate_timeout 调成大于nginx 的等待时间
参考
https://segmentfault.com/a/1190000002686153
php-fpm参数调优