首先得了解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