首先得了解502错误的定义(http://www.checkupdown.com/status/E502_zh.html)以及主要是考虑是否是代理(访问的上游)出了问题php
查询php-fpm的日志能够发现有php运行超时的记录html
...前端
[pool www] child 27343, script '/usr/local/tengine/html/index.php' (request: "POST /index.php") executing too slow (3.196879 sec), loggingnode
......linux
想到的是哪些参数会决定了php执行的超时时间:nginx
如下摘自章小鱼儿_linux博客的一些内容(http://zhangxylinux.blog.51cto.com/5041623/1543035) sql
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 nosql
max_execution_timesocket
计算的只是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