淺談PHP-FPM引數

Uchiha_Ponny發表於2019-02-16

process_control_timeout

英文解釋

process_control_timeout
 mixed
Time limit for child processes to wait for a reaction on signals from master. Available units: s(econds), m(inutes), h(ours), or d(ays) Default Unit: seconds. Default value: 0.

中文翻譯

process_control_timeout
 mixed
設定子程式接受主程式複用訊號的超時時間。可用單位:s(秒),m(分),h(小時)或者 d(天)。預設單位:s(秒)。預設值:0(關閉)。

中文翻譯有個不恰當的地方,英文解釋裡並沒有指明該訊號是複用訊號。

我的理解:

  • 處理請求

原則上,php-fpm會選擇空閒的fastcgi程式去處理請求,在處理之前,php-fpm會給fastcgi傳送訊號,用來讓fastcgi程式準備好接受請求處理。但是fastcgi程式並不總是能夠處理請求,也就是不能總是響應該訊號(比如出現假死的情況),這時候就需要設定php-fpm留給fastcgi程式響應訊號的時間,如果超時了,php-fpm會想其他辦法(例如選擇其他fastcgi程式),這個就是process_control_timeout引數的作用

  • php-fpm進行reload

process_control_timeout = 10

http://localhost
<?php 
sleep(50);
echo 1;
sleep(20);    //沒有這個sleep,reload會立即生效
echo 2;

當瀏覽器訪問http://localhost時,進行php-fpm平滑reload,fastcgi訊號收到關閉程式訊號後,第一個sleep函式會直接返回,但是第二個sleep仍在執行。因此,php-fpm會被這一個舊fastcgi程式卡10s,超過後才能完成平滑重啟


request_terminate_timeout

在php-fpm.conf檔案中的描述如下:

; The timeout for serving a single request after which the worker process will
; be killed. This option should be used when the `max_execution_time` ini option
; does not stop script execution for some reason. A value of `0` means `off`.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
;request_terminate_timeout = 0

翻譯過來就是:
request_terminate_timeout引數設定了處理單個請求的超時時間,過了之後,該worker程式就會被kill掉。這個選項應該在php.ini檔案的max_execution_time選項由於某種原因沒有停止指令碼的執行下使用。預設值為0,表示該選項為關閉狀態。

正如上面所說,request_terminate_timeout設定的是請求的超時時間,而php.ini配置中的max_execution_time根據手冊如下的解釋,是指令碼被允許的最大執行時間。

max_execution_time
 integer
這設定了指令碼被解析器中止之前允許的最大執行時間,單位秒。 這有助於防止寫得不好的指令碼佔盡伺服器資源。 預設設定為 30。 從命令列執行 PHP 時,預設設定為 0
最大執行時間不會影響系統呼叫和系統操作等。更多細節參見 set_time_limit()
在 安全模式 下你不能通過 ini_set() 來修改此設定。 唯一的解決方法是關閉安全模式或者在 php.ini中修改時間限制。
你的 web 伺服器也可以有其他超時設定,也有可能中斷 PHP 的執行。 Apache 有一個 Timeout 指令,IIS 有一個 CGI 超時功能。 他們預設都是 300 秒。更多具體資訊參見你的 web 伺服器的文件。

區別如下:

  1. 超時後,request_terminate_timeout會返回502Bad Gateway了,而max_execution_time會丟擲Fatal Error。
  2. max_execution_time不包括諸如使用system()sleep()的系統呼叫、流操作、資料庫操作等的時間,所以比較雞肋,而request_terminate_timeout會包含程式的完整請求時間。

另外,開啟request_terminate_timeout並不會讓max_execution_time失效,先到達誰的超時時間誰起作用。

相關文章