前段時間一位同事跟我說php腳本超時時間以fpm配置優先。通過本身測試後,其實否則,前面的觀點只是在某些狀況下成立。php
php腳本超時時間能夠在php.ini的max_execution_time和fpm.conf的request_terminate_timeout參數兩處進行設置.那麼這二者有什麼區別呢?linux
當咱們設置php.ini的max_execution_time參數後,zend引擎處理腳本時,其內部會根據設定的時間定義一個定時器(setitimer),這是linux的API。chrome
而fpm.confrequest_terminate_timeout的檢測是經過主進程遍歷定時事件fpm_pctl_heartbeat來判斷PHP腳本執行是否超時。數據庫
下面經過實例進行分析。瀏覽器
example:安全
$a = time(); var_dump('begin'); for($i=0;;$i++){ if(time()-$a>10){ break; } } var_dump('end');
上面的代碼比較容易理解,首先,輸出「begin」字符串,10秒後再輸出「end」字符串。函數
方案1:修改php.ini的配置max_execution_time=3,fpm.conf的request_terminate_timeout=20.測試
example執行的結果:spa
string(5) "begin"
1
chrome瀏覽器抓包:.net
根據上面運行的結果和效果圖能夠看出,example運行3秒後停止。也就是說,此時,php.ini的max_execution_time生效了。
方案2:修改php.ini的配置max_execution_time=20,fpm.conf的request_terminate_timeout=3.
example執行的結果:
chrome瀏覽器抓包:
從上面的截圖能夠看出,程序也只執行了3S。此時腳本的運行受到fpm.conf的request_terminate_timeout配置影響。
從上面兩個方案推斷出,對於example實例,php腳本取max_execution_time與request_terminate_timeout最小值做爲腳本的超時時間。那是否是隻要設置max_execution_time參數便可呢?
下面繼續分析,咱們對example代碼稍微調整下。
$a = time(); var_dump('begin'); sleep(10); var_dump('end');
這段代碼與上面功能相似,惟一的區別是由循環改爲sleep()。
採用方案1的配置,結果以下:
string(5) "begin" string(3) "end"
1
採用方案2的配置,結果以下:
example執行的結果:
對比兩個結果能夠看出此時max_execution_time的配置未起到效果。如下是引用php手冊的一段話(http://php.net/manual/zh/func...:
set_time_limit()函數和配置指令max_execution_time隻影響腳本自己執行的時間。任何發生在諸如使用system()的系統調用,流操做,數據庫操做等的腳本執行的最大時間不包括其中,當該腳本已運行。在測量時間是實值的Windows中,狀況就不是如此了。
SO,爲了保證生產環境的安全,建議同時設置max_execution_time和request_terminate_timeout參數值。