首先得了解502错误的定义(http://www.checkupdown.com/status/E502_zh.html)以及主要是考虑是不是代理(访问的上游)出了问题
查询php-fpm的日志可以发现有php运行超时的记录
...
[pool www] child 27343, script '/usr/local/tengine/html/index.php' (request: "POST /index.php") executing too slow (3.196879 sec), logging
......
想到的是哪些参数会决定了php执行的超时时间:
以下摘自章小鱼儿_linux博客的一些内容(http://zhangxylinux.blog.51cto.com/5041623/1543035)
PHP自身配置:
在php.ini里max_execution_time可以设置php脚本的最大执行时间,但是在php-cgi(php-fpm)中,该参数不生效,真正能控制php最大执行时间的是request_terminate_timeout,就是说如果是使用 mod_php5.so 的模式运行 max_execution_time 是会生效的,但是如果是php-fpm模式中运行时不生效的。参数优先级 nginx > php-fpm > php
max_execution_time
计算的只是PHP脚本本身执行的时间,执行之外的时间都不会计算在内。哪些属于执行之外的时间呢?包含sleep、数据交互、socket交互等等。
request_terminate_timeout = 0 即为不受时间控制,永不超时
3.request_terminate_timeout引起的资源问题
request_terminate_timeout的值如果设置为0或者过长的时间,可能会引起file_get_contents的资源问题。
如果file_get_contents请求的远程资源如果反应过慢,file_get_contents就会一直卡在那里不会超时。request_terminate_timeout默认值为 0 秒,也就是说,PHP 脚本会一直执行下去。这样,当所有的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。修改该参数,设置一个 PHP 脚本最大执行时间是必要的,但是,治标不治本。例如改成 30s,如果发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟只能处理 5 个请求,WebServer 同样很难避免”502 Bad Gateway”。解决办法是request_terminate_timeout设置为10s或者一个合理的值,或者给file_get_contents加一个超时参数
如果常有请求超时,请打开php-fpm的慢日志,通过日志来确认评估超时时间
4.
Ngnix中的fastcgi 请求时间控制
fastcgi_connect_timeout
语法:fastcgi_connect_timeout time
默认值:fastcgi_connect_timeout 60
使用字段:http, server, location
指定同FastCGI服务器的连接超时时间,这个值不能超过75秒。
fastcgi_read_timeout
语法:fastcgi_read_timeout time
默认值:fastcgi_read_timeout 60
使用字段:http, server, location
前端FastCGI服务器的响应超时时间,如果有一些直到它们运行完才有输出的长时间运行的FastCGI进程,或者在错误日志中出现前端服务器响应超时错误,可能需要调整这个值。
fastcgi_send_timeout
语法:fastcgi_send_timeout time
默认值:fastcgi_send_timeout 60
使用字段:http, server, location
指令为上游服务器设置等待一个FastCGI进程的传送数据时间,如果有一些直到它们运行完才有输出的长时间运行的FastCGI进程,那么可以修改这个值,如果你在上有服务器的error log里面发现一些超时错误,那么可以恰当的增加这个值。
指令指定请求服务器的超时时间,指完成了2次握手的连接,而不是完整的连接,如果在这期间客户端没有进行数据传递,那么服务器将关闭这个连接。
在nginx+FastCGI 配置测试中
其中在request_terminate_timeout设置为永不超时的情况下,nginx中fastcgi_read_timeout 的设置时间将影响到最终的超时时间。
测试中,如果是php-fpm中的超时
将显示 502 Bad Gateway
如果是nginx中cgi配置超时
将显示 504 Gateway Time-out
但是经过分析服务器上没有出现所有 php-cgi 进程都卡在 file_get_contents()上
继续查看日志发现以下内容:
WARNING: [pool www] child 407 exited on signal 11 (SIGSEGV) after 3409158.647209 seconds from start
查询系统日志也能发现类似问题
php-fpm[407]: segfault at c5a1 ip 00000000007cd1cc sp 00007fff74640bc0 error 4 in php-fpm[400000+949000]
发现进程遇到段错误异常退出了,但是系统并没有开启core文件,暂时不能定位了
如何发现段错误:
查看限制情况:
系统对于core文件大小默认限制是0.也就是说不能生成core文件。可以通过以下命令设置大小。
执行ulimit -c unlimited
就去除了系统对core文件大小的限制,接下来我们就可以根据产生的core文件去定位问题了
利用GDB调试php core dump
应用程序因异常或bug异常退出在一定条件下会产生core文件
开启core
设置core路径
echo "/tmp/core.%p" > /proc/sys/kernel/core_pattern
修改unlimit(略)
重启php-fpm
查看core文件
gdb /usr/local/php/sbin/php-fpm -c core_file_path
.....
//查看调用栈
(gdb)bt
....
还可以利用php提供的.gdbinit(gdb命令编写脚本)帮我们查看php函数层的调用
(gdb)source /usr/local/src/autoinst.nmp_nosql_node_php54/php-5.4.30/.gdbinit
(gdb)zbacktrace
参考链接:
http://zhangxylinux.blog.51cto.com/5041623/1543035
https://yq.aliyun.com/articles/27468
http://www.vckai.com/p/38
转载于:https://blog.51cto.com/itfun/1896016