標籤:
第一點: request_terminate_timeout引起的資源問題 request_terminate_timeout的值如果設定為0或者過長的時間,可能會引起file_get_contents的資源問題。如果file_get_contents請求的遠端資源如果反應過慢,file_get_contents就會一直卡在那裡不會逾時。
我們知道php.ini 裡面max_execution_time 可以設定 PHP 指令碼的最大執行時間,但是,在 php-cgi(php-fpm) 中,該參數不會起效。真正能夠控制 PHP 指令碼最大執行時間的是 php-fpm.conf 設定檔中的request_terminate_timeout參數。 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加一個逾時參數。 $ctx = stream_context_create(array( ‘http‘ => array( ‘timeout‘ => 10 //設定一個逾時時間,單位為秒 )));file_get_contents($str, 0, $ctx); 第二點:max_requests參數配置不當,可能會引起間歇性502錯誤:pm.max_requests = 1000;設定每個子進程重生之前服務的請求數. 對於可能存在記憶體流失的第三方模組來說是非常有用的. 如果設定為 ’0′ 則一直接受請求. 等同於 PHP_FCGI_MAX_REQUESTS 環境變數. 預設值: 0.這段配置的意思是,當一個 PHP-CGI 進程處理的請求數累積到 1000 個後,自動重啟該進程。但是為什麼要重啟進程呢?一般在項目中,我們多多少少都會用到一些 PHP 的第三方庫,這些第三方庫經常存在記憶體流失問題,如果不定期重啟 PHP-CGI 進程,勢必造成記憶體使用量量不斷增長。因此 PHP-FPM 作為 PHP-CGI 的管理器,提供了這麼一項監控功能,
對請求達到指定次數的 PHP-CGI 進程進行重啟,保證記憶體使用量量不增長。
正是因為這個機制,在高並發的網站中,經常導致 502 錯誤,我猜測原因是 PHP-FPM 對從 NGINX 過來的請求隊列沒處理好。不過我目前用的還是 PHP 5.3.2,不知道在 PHP 5.3.3 中是否還存在這個問題。目前我們的解決方案是,把這個值盡量設定大些,儘可能減少 PHP-CGI 重新 SPAWN(產卵) 的次數,同時也能提高總體效能。在我們自己實際的生產環境中發現,記憶體流失並不明顯,因此我們將這個值設定得非常大(204800)。大家要根據自己的實際情況設定這個值,不能盲目地加大。話說回來,這套機制目的只為保證 PHP-CGI 不過分地佔用記憶體,為何不通過檢測記憶體的方式來處理呢?我非常認同高春輝所說的,通過設定進程的峰值內在佔用量來重啟 PHP-CGI 進程,會是更好的一個解決方案。
綜上,針對fpm重啟的觀點,本人認為可以利用 在fpm中進程池的概覽,我們可以設定多個進程池;
[www]
user = www
group = www
listen = 127.0.0.1:9001
pm = dynamic
pm.max_children = 500
pm.start_servers = 200
pm.min_spare_servers = 100
pm.max_spare_servers = 300
[www]
user = www
group = www
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 500
pm.start_servers = 200
pm.min_spare_servers = 100
pm.max_spare_servers = 300
nginx 配置
機器A nginx.conf配置
#在http 地區中增加:
upstream backend{
server 127.0.0.1:9000 weight=1;
server 127.0.0.1:9001 weight=2;
keepalive 3072;
}
#在server 內如下配置
location ~ .*\.php
{
fastcgi_pass backend;
fastcgi_index index.php;
include fastcgi.conf;
}
502 Bad Gateway(PHP的角度來分析)