分析php代码报502的错

首先得了解502错误的定义(http://www.checkupdown.com/status/E502_zh.html)以及主要是考虑是否是代理(访问的上游)出了问题php


查询php-fpm的日志能够发现有php运行超时的记录html

spacer.gifwKiom1iasAiQe8kRAABISOCsWWU679.png-wh_50

...前端

[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自身配置:服务器

  1. 在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

  2. max_execution_timesocket

  3. 计算的只是PHP脚本自己执行的时间,执行以外的时间都不会计算在内。哪些属于执行以外的时间呢?包含sleep、数据交互、socket交互等等。 

  4. request_terminate_timeout = 0  即为不受时间控制,永不超时


3.request_terminate_timeout引发的资源问题

  1. request_terminate_timeout的值若是设置为0或者过长的时间,可能会引发file_get_contents的资源问题。

  2. 若是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.

  1. Ngnix中的fastcgi 请求时间控制

  2. fastcgi_connect_timeout

  3. 语法:fastcgi_connect_timeout time 

  4. 默认值:fastcgi_connect_timeout 60 

  5. 使用字段:http, server, location 

  6. 指定同FastCGI服务器的链接超时时间,这个值不能超过75秒。


  7. fastcgi_read_timeout

  8. 语法:fastcgi_read_timeout time 

  9. 默认值:fastcgi_read_timeout 60 

  10. 使用字段:http, server, location 

  11. 前端FastCGI服务器的响应超时时间,若是有一些直到它们运行完才有输出的长时间运行的FastCGI进程,或者在错误日志中出现前端服务器响应超时错误,可能须要调整这个值。


  12. fastcgi_send_timeout

  13. 语法:fastcgi_send_timeout time 

  14. 默认值:fastcgi_send_timeout 60 

  15. 使用字段:http, server, location 

  16. 指令为上游服务器设置等待一个FastCGI进程的传送数据时间,若是有一些直到它们运行完才有输出的长时间运行的FastCGI进程,那么能够修改这个值,若是你在上有服务器的error log里面发现一些超时错误,那么能够恰当的增长这个值。

  17. 指令指定请求服务器的超时时间,指完成了2次握手的链接,而不是完整的链接,若是在这期间客户端没有进行数据传递,那么服务器将关闭这个链接。


  1. 在nginx+FastCGI 配置测试中

  2. 其中在request_terminate_timeout设置为永不超时的状况下,nginx中fastcgi_read_timeout 的设置时间将影响到最终的超时时间。

  3. 测试中,若是是php-fpm中的超时

  4. 将显示 502 Bad Gateway

  5. 若是是nginx中cgi配置超时

  6. 将显示 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

wKioL1ias4LR0bneAABx-2uRJo0598.jpg-wh_50

查询系统日志也能发现相似问题

php-fpm[407]: segfault at c5a1 ip 00000000007cd1cc sp 00007fff74640bc0 error 4 in php-fpm[400000+949000]

wKiom1iatUTDnF9fAAEeGs2AGgQ970.png-wh_50

发现进程遇到段错误异常退出了,可是系统并无开启core文件,暂时不能定位了

如何发现段错误:

查看限制状况:

wKiom1iatfaw3tL-AAA7MbK14-s668.jpg-wh_50

系统对于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

相关文章
相关标签/搜索