nginx+FastCGI到底是誰影響超時時間

需求:

一個php程序要跑一段時間,但是時間不確定。

問題:    

當該php程序運行超過一段時間被強制斷開連接。

PHP本身超時處理

在 php.ini 中,有一個參數 max_execution_time 可以設置 PHP 腳本的最大執行時間,但是,在 php-cgi(php-fpm) 中,該參數不會起效。真正能夠控制 PHP 腳本最大執行時:

 

<value name="request_terminate_timeout">0s</value>  

 

就是說如果是使用 mod_php5.so 的模式運行 max_execution_time 是會生效的,但是如果是php-fpm模式中運行時不生效的。

max_execution_time

計算的只是PHP腳本本身執行的時間,執行之外的時間都不會計算在內。哪些屬於執行之外的時間呢?包含sleep、數據交互、socket交互等等。 

request_terminate_timeout = 0  即爲不受時間控制,永不超時


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加一個超時參數

如果常有請求超時,請打開php-fpm的慢日誌,通過日誌來確認評估超時時間。

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

<html>

<head><title>502 Bad Gateway</title></head>

<body bgcolor="white">

<center><h1>502 Bad Gateway</h1></center>

<hr><center>nginx</center>

</body>

</html>

如果是nginx中cgi配置超時

將顯示 504 Gateway Time-out

<html>

<head><title>504 Gateway Time-out</title></head>

<body bgcolor="white">

<center><h1>504 Gateway Time-out</h1></center>

<hr><center>nginx</center>

</body>

</html>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章