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

PHP-FPM 進程管理:平滑重啟、關閉與信號控制完整指南

     編輯:PHP 相關知識

什麼是 PHP-FPM?

PHP-FPM (FastCGI Process Manager) 是 PHP 官方內建的 FastCGI 進程管理器,自 PHP 5.3.3 起整合入核心。它採用 Master-Worker 架構:Master 進程負責管理 Worker 池、接收信號、平滑重載配置;Worker 進程實際處理請求。相較於舊式 spawn-fcgi,FPM 提供更精細的進程控制、記憶體限制、慢日誌、狀態頁面等企業級功能。

Master 進程可識別的信號

信號動作使用場景
INT / TERM立即終止所有進程(強制關閉)緊急停機、容器關閉
QUIT平滑終止:完成當前請求後退出計劃性維護、部署前停機
USR1重新打開日誌檔案(logrotate 配合)日誌切割、釋放磁碟空間
USR2平滑重載:重新讀取配置、重啟 Worker、平滑切換修改 php.ini / php-fpm.conf 後生效、程式碼部署

常用操作指令(假設 pid 檔路徑為 /usr/local/php/var/run/php-fpm.pid)

1. 平滑重載(最常用,零停機部署)

kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`

Master 會依序:
1. 重新讀取配置檔
2. 啟動新 Worker 池
3. 舊 Worker 處理完當前請求後自動退出
4. 新 Worker 完全接管流量

2. 平滑關閉

kill -QUIT `cat /usr/local/php/var/run/php-fpm.pid`

3. 強制關閉(慎用)

kill -TERM `cat /usr/local/php/var/run/php-fpm.pid`

4. 重新打開日誌

kill -USR1 `cat /usr/local/php/var/run/php-fpm.pid`

5. 檢查進程數

ps aux | grep -c php-fpm
# 或更精確
pgrep -c php-fpm

替代方案:systemd 管理(現代 Linux 標準)

若透過套件管理器安裝(如 yum install php-fpm 或 apt install php8.2-fpm),建議直接使用 systemd:

# 重載配置(平滑)
sudo systemctl reload php-fpm

# 重啟服務(會短暫中斷,約 100-500ms)
sudo systemctl restart php-fpm

# 停止
sudo systemctl stop php-fpm

# 查看狀態
sudo systemctl status php-fpm

# 即時追蹤日誌
sudo journalctl -u php-fpm -f

進階:php-fpm.conf 關鍵配置解析

; 進程管理模式
pm = dynamic              ; static / dynamic / ondemand
; static: 固定數量 Worker
; dynamic: 根據負載動態調整(需設定 pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers)
; ondemand: 有請求才啟動 Worker,閒置超時關閉(適合低流量)

pm.max_children = 50      ; 最大 Worker 數(依記憶體估算:總記憶體 / 單進程記憶體)
pm.start_servers = 10     ; 啟動時 Worker 數
pm.min_spare_servers = 5  ; 最小閒置 Worker
pm.max_spare_servers = 20 ; 最大閒置 Worker

; 請求生命週期控制
pm.max_requests = 1000    ; 每個 Worker 處理 1000 請求後重生(防記憶體洩漏)
request_terminate_timeout = 60s  ; 單請求最長執行時間
request_slowlog_timeout = 5s     ; 慢日誌門檻
slowlog = /var/log/php-fpm/www-slow.log

; 記憶體保護
php_admin_value[memory_limit] = 256M

; 狀態頁面(需 nginx 配合 location /fpm-status)
pm.status_path = /fpm-status
ping.path = /fpm-ping

Worker 記憶體估算公式

可用記憶體 = 總實體記憶體 - 系統保留 - MySQL/Redis 等其他服務記憶體
單進程記憶體 ≈ 30-50 MB (視框架、擴展而定,Laravel 约 40-60MB)
建議 max_children = 可用記憶體 / 單進程記憶體 * 0.8 (留 20% 緩衝)

# 範例:4GB 記憶體,系統保留 1GB,MySQL 1GB,剩 2GB
# 單進程 40MB => 2048 / 40 ≈ 51 * 0.8 ≈ 40
pm.max_children = 40

常見問題排查

1. 重載後配置不生效

  • 確認修改的是正確的 pool 設定檔(通常在 /etc/php-fpm.d/www.conf)
  • 執行 php-fpm -t 測試語法
  • 查看 Master 進程日誌是否有 reloading configuration 訊息

2. 平滑重載卡住、Worker 不退出

  • 檢查是否有長時間執行的腳本(request_terminate_timeout 設定過大或腳本 ignore_user_abort(true))
  • 檢查資料庫連線是否未正確關閉導致 Worker 掛起
  • 強制終止:kill -TERM `cat pid` 後再啟動

3. 502 Bad Gateway

  • Worker 全滿(pm.max_children 過小)
  • Worker 崩潰(查看 /var/log/php-fpm/error.log)
  • Nginx upstream 指向錯誤的 socket 路徑或埠號

容器化環境最佳實踐

# Dockerfile 片段
FROM php:8.2-fpm-alpine

# 使用 dumb-init 作為 PID 1 處理信號轉發
RUN apk add --no-cache dumb-init
ENTRYPOINT ["dumb-init", "--"]
CMD ["php-fpm"]

# docker-compose.yml
services:
  php:
    build: .
    # 平滑重載支援
    stop_signal: SIGQUIT
    # 健康檢查
    healthcheck:
      test: ["CMD-SHELL", "php-fpm -t"]
      interval: 30s
      timeout: 10s
      retries: 3

掌握 PHP-FPM 信號控制與配置調優,是保障 PHP 應用高可用、零停機部署的核心技能。建議將平滑重載納入 CI/CD 流程,實現真正的持續部署。

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