[筆記] 延長 PHP-FPM 和 NGINX 執行時間上限

Laravel 或是一般 PHP 專案上常會遇到執行時間超時的問題,
例如遇到了 PHP 超過執行時間上限的錯誤:

'production.ERROR: Maximum execution time of 30 seconds exceeded'

或是遇到 NGINX 的超時錯誤:

'504 Gateway Time-out'

是因為 PHP 和 NGINX 預設最長執行時間都是 30 秒,我們可以修改設定來延長它們。這裡我們延長到 Apache、IIS 慣例的 5 分鐘。

這個主題其實很多人寫了,但是資訊有點零散,乾脆自己再寫一篇方便以後找。(感覺就是很常會改啊)

PHP: 延長 max_execution_time

PHP 的 runtime 設定中的 max_execution_time 參數可以指定腳本被 parser 中止之前允許的最大執行時間,預設值是 30 秒。我們可以透過修改 php.ini 指定為 300 秒。

修改 php.ini

以 PHP 7.2 為例,php.ini 的位置預設是在 /etc/php/7.2/cli/php.ini。php.ini 的位置可以經由 php -i 指令查詢的到。順帶一提,PHPBrew 使用者可以透過 phpbrew config 指令直接開啟當前版本對應的 php.ini。

; /etc/php/7.2/cli/php.ini
;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;

; Maximum execution time of each script, in seconds
; http://php.net/max-execution-time
; Note: This directive is hardcoded to 0 for the CLI SAPI
max_execution_time = 300

重新啟動 PHP-FPM

修改完成後,需要重新啟動 PHP-FPM。

  • PHPBrew 使用者
phpbrew fpm restart
  • Ubuntu/Debian 系
sudo service php7.2-fpm restart
  • CentOS/RHEL 7 系
sudo systemctl restart php-fpm

NGINX: 延長 fastcgi_read_timeout

NGINX 的部分則是透過 fastcgi_read_timeout 這個參數來決定 PHP FastCGI Server(PHP-FPM)的 Response 時間限制,預設是 30 秒,我們也把它改成 300 秒。

修改 nginx.conf

這裡我們直接在 /etc/nginx/nginx.confhttp 內容區塊中設定,就會套用到所有站點。你也可以選擇在各自的 Server config 裡的 serverlocation 內容區塊中指定不同的時間限制。

# /etc/nginx/nginx.conf
http {
        ##
        # Basic Settings
        ##

		# 以上省略...
        fastcgi_read_timeout 300s;
  		# 以下省略...

重新載入設定

修改完成後,需要讓 NGINX 讀取新的設定檔。

sudo nginx -t        # 測試設定檔有無問題
sudo nginx -s reload # 重新讀取設定檔

關於 PHP-FPM 的額外設定

Increase PHP script execution time with Nginx 這篇文中還有提到,如果你曾經設定過 PHP-FPM 的 request_terminate_timeout,也要記得改哦!

這個值預設是被註解掉、直接關聯到 php.ini 的 max_execution_time,官方建議 max_execution_time 有問題的話才使用它。

如果要修改或檢查的話,預設是在 /etc/php/7.2/fpm/pool.d/www.conf 修改。PHPBrew 使用者可以透過 phpbrew fpm config 打開當前版本的 www.conf 檔。

; /etc/php/7.2/fpm/pool.d/www.conf
request_terminate_timeout = 300