首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP-FPM (FastCGI) 執行時間超時完整排查與配置指南

     編輯:PHP 綜合知識

Nginx + PHP-FPM 架構下,max_execution_time、set_time_limit() 有時失效,真兇往往是 PHP-FPM 自身的 request_terminate_timeout 或 Nginx 反向代理超時設定。本文完整記錄一次 504 Gateway Timeout 排查實戰。

三層超時機制

  1. PHP 層:php.ini: max_execution_time、ini_set()、set_time_limit()(僅計算 CPU 時間,不含 I/O 等待)。
  2. PHP-FPM 層:php-fpm.conf: request_terminate_timeout(硬性殺掉超時 Worker 進程,預設 30s)。
  3. Nginx 層:proxy_read_timeout、proxy_send_timeout、proxy_connect_timeout(預設 60s)。

實戰排查過程

現象

導出 500 筆資料,約 150 筆時 Nginx 拋 504。觀察約 30 秒超時,但 php.ini 已設 max_execution_time = 300。

驗證 PHP 設定是否生效

<?php
echo 'aaa';
set_time_limit(0); // 0 = 無限制
sleep(40);
echo 'aa';
?>

結果:依然 30 秒超時 → set_time_limit 失效。

鎖定 PHP-FPM 配置

# php-fpm.conf
<value name="request_terminate_timeout">30s</value>

官方文檔:「當 max_execution_time 無法停止腳本時生效,預設 5s,0s 代表關閉」。此參數為**硬性殺進程**,優先級高於 PHP 內部計時。

解決方案

# 方案一:調大至業務所需(如 300 秒)
<value name="request_terminate_timeout">300s</value>

# 方案二:關閉(生產環境建議設定具體值,防止佔用 Worker)
<value name="request_terminate_timeout">0s</value>

修改後 **reload php-fpm** 生效,程式正常跑完 40 秒睡眠。

Nginx 反向代理超時同步調整

若使用 upstream 負載均衡,必須同步調整:

location / {
    proxy_pass https://backend;
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s; # 最關鍵:讀取 FastCGI 回應的超時
    # fastcgi_read_timeout 300s; # 若直接 fastcgi_pass
}

最佳實踐總結

  1. 三層同步:PHP max_execution_time ≤ PHP-FPM request_terminate_timeout ≤ Nginx proxy_read_timeout。
  2. 業務拆分:長耗時任務(匯出、報表、同步)改為**非同步佇列**(Redis/RabbitMQ + Worker),HTTP 請求僅發起任務並輪詢/回調結果,避免長連線佔用 Worker。
  3. 監控告警:監控 request_terminate_timeout 觸發次數,發現長耗時腳本優化或異步化。
  4. 版本差異:PHP 7.1+ max_execution_time 開始計入部分系統呼叫時間,但仍不含網路 I/O,PHP-FPM 層防線不可少。

搞懂三層超時關係,不再為莫名的 504、502 發呆,長任務乖乖走佇列才是正道。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved