PHP-FPM (FastCGI Process Manager) 是 PHP 生產環境的標準運行模式。正確配置 php-fpm.conf 與池配置 www.conf,能顯著提升吞吐量、降低延遲、防止內存洩漏導致的 502 錯誤。本文逐項解讀核心參數,並提供不同場景的調優建議。
| 參數 | 默認值 | 建議值/說明 |
|---|---|---|
pid | var/run/php-fpm.pid | 建議啟用,便於監控腳本發送信號 |
error_log | var/log/php-fpm.log | 單獨存放,方便 ELK 收集 |
log_level | notice | 生產環境 warning;調試時 debug |
emergency_restart_threshold | 60 | 配合 interval 使用,防止子進程頻繁 Segfault 拖垮主進程 |
emergency_restart_interval | 60s | 同上 |
process_control_timeout | 0 | 子進程等待主進程信號超時,建議 5-10s |
daemonize | yes | 生產必須 yes;容器化/前台調試改 no |
| 模式 | 適用場景 | 關鍵參數 |
|---|---|---|
static | 專用高配服務器、流量穩定、追求極致性能 | pm.max_children 固定進程數 |
dynamic | 通用場景、共享主機、流量波動大 | max_children, start_servers, min_spare_servers, max_spare_servers |
ondemand | 低流量、間歇性請求、節省記憶體 | max_children, process_idle_timeout |
; 假設服務器 4GB 內存,系統/其他佔 1GB,留 3GB 給 PHP-FPM
; 單進程平均內存 30MB (含 opcode cache、擴展、請求上下文)
pm.max_children = 3072 / 30 ≈ 100
pm.start_servers = 20 ; 啟動時預熱進程數
pm.min_spare_servers = 10 ; 空閒最小值,低於此創建新進程
pm.max_spare_servers = 30 ; 空閒最大值,高於此回收進程
; 關鍵:防止內存洩漏累積
pm.max_requests = 500 ; 每進程處理 500 請求後重生 (0=不限)
; 配合 opcache.revalidate_freq=60 實現代碼熱更新
; 請求硬性超時 (對應 Nginx fastcgi_read_timeout 需一致或略小)
request_terminate_timeout = 30s ; 0=關閉,建議 30-60s
; 慢日誌:超過此時間記錄完整調用堆棧
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/www-slow.log
; 狀態頁面 (需 Nginx location /status 轉發)
pm.status_path = /status
ping.path = /ping
ping.response = pong
; 文件描述符上限 (ulimit -n 需同步調大)
rlimit_files = 65535
; 核心轉儲大小 (調試 coredump 時設 unlimited)
rlimit_core = 0
; 安全加固
; chroot = /var/www ; 啟用 chroot 隔離 (需完整根目錄)
; chdir = /var/www/html ; 啟動工作目錄
catch_workers_output = yes ; 將 stdout/stderr 導向 error_log
user = www-data
group = www-data
; 傳遞環境變量給 PHP 腳本
env[HOSTNAME] = $HOSTNAME
env[APP_ENV] = production
env[DB_HOST] = 127.0.0.1
pm = static
pm.max_children = 300
pm.max_requests = 1000
request_terminate_timeout = 20s
request_slowlog_timeout = 2s
rlimit_files = 65535
pm = dynamic
pm.max_children = 80
pm.start_servers = 15
pm.min_spare_servers = 10
pm.max_spare_servers = 25
pm.max_requests = 500
request_terminate_timeout = 30s
request_slowlog_timeout = 5s
pm = ondemand
pm.max_children = 20
pm.process_idle_timeout = 60s
pm.max_requests = 200
request_terminate_timeout = 60s
https://host/status?full&json 獲取實時進程狀態、請求耗時、內存用量。grep -A 20 \"script_filename\" www-slow.log | head -50 定位慢查詢、外部 API 阻塞、死循環。watch -n 1 'ps aux | grep php-fpm | wc -l' 觀察動態伸縮情況。pm.max_requests 強制重生 + memory_get_peak_usage() 記錄峰值。location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock; # 或 127.0.0.1:9000
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# 超時必須 ≤ FPM request_terminate_timeout
fastcgi_read_timeout 30s;
fastcgi_send_timeout 30s;
# 緩衝區優化大文件上傳/下載
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
}
核心原則:Nginx 超時 ≤ FPM 超時,避免 Nginx 先切斷連接導致 FPM 繼續佔用進程處理已無客戶端的請求。