核心概念釐清
| 術語 | 本質 | 說明 |
| CGI | 協議規範 | Common Gateway Interface,定義 Web Server 與外部程式溝通的標準(環境變數、STDIN/STDOUT)。 |
| FastCGI | 協議規範 | CGI 增強版:**長駐進程**、單進程處理多請求、支援分布式(TCP Socket)、減少 fork/open 開銷。 |
| PHP-CGI | 程式實現 | PHP 官方提供的 FastCGI 進程管理器(單主進程,無平滑重啟、無進程監控)。 |
| PHP-FPM | 程式實現 | PHP FastCGI Process Manager,**管理 PHP-CGI 進程池**:平滑重啟、動態/靜態進程數、狀態監控、慢日誌、權限隔離。 |
為什麼從 CGI 進化到 FastCGI?
# CGI 模式(每請求一進程)
Request → Web Server → fork() → CGI 程式 → 處理 → exit → 回應
缺點:頻繁 fork/exec、重複載入 php.ini/擴充、無法共享資源(DB 連線池、OPcache)。
# FastCGI 模式(長駐進程池)
Web Server ←→ Socket/TCP ←→ FastCGI Manager (PHP-FPM) ←→ Worker Pool (多 php-cgi)
優點:進程複用、啟動時載入一次 php.ini/擴充、持久連線、可跨機器部署 Worker。
PHP-CGI vs PHP-FPM 關鍵差異
| 特性 | PHP-CGI | PHP-FPM |
| 進程管理 | 單主進程,手動啟動 | Master + 多 Worker,支援動態/靜態/ondemand 模式 |
| 平滑重啟 | ❌ 殺進程即服務中斷 | ✅ reload 逐步換新 Worker,零停機 |
| 進程監控/自動重生 | ❌ | ✅ Master 監控 Worker,異常自動拉起 |
| 慢日誌/請求追蹤 | ❌ | ✅ request_slowlog_timeout、slowlog |
| 權限隔離 | ❌ | ✅ user/group/chroot/chdir |
| 狀態頁面 | ❌ | ✅ pm.status_path 即時監控 |
| 生產環境建議 | ❌ 不推薦 | ✅ **標準生產部署方式** |
Nginx 如何調用 PHP(FastCGI 流程)
# nginx.conf 核心配置
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000; # 或 unix:/run/php/php8.1-fpm.sock
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params; # 包含標準 CGI 環境變數
}
完整請求流程
- Nginx 接收請求
/index.php?foo=bar。
- 匹配
location ~ \.php$,構建 FastCGI 協議封包(環境變數:REQUEST_METHOD、SCRIPT_FILENAME、QUERY_STRING、HTTP_* 等 + 請求體)。
- 經 Unix Socket/TCP 發送給 PHP-FPM Master。
- Master 挑選空閒 Worker(php-cgi 進程)處理。
- Worker 解析封包、初始化
$_GET/$_POST/$_SERVER、執行 PHP 腳本。
- Worker 將輸出(Header + Body)按 FastCGI 協議回傳給 Nginx。
- Nginx 組裝 HTTP 回應返回瀏覽器。
- Worker **不退出**,繼續等待下一請求。
Apache 調用 PHP 三種模式對比
| 模式 | 架構 | 效能 | 穩定性 | 現狀 |
| mod_php (DSO) | PHP 內嵌 Apache 進程 | 高(無進程切換) | 低(PHP 崩潰拖垮 Apache、記憶體洩漏累積) | **棄用**,PHP 8.0+ 官方不再提供 |
| mod_fcgid | Apache 管理 FastCGI 進程 | 中 | 中 | 較少用 |
| PHP-FPM + mod_proxy_fcgi | Nginx 同模式,FPM 獨立管理進程 | 高 | 高(進程隔離、平滑重啟) | **推薦** |
FastCGI 進程模型深度剖析
# PHP-FPM 進程樹
php-fpm: master process (php-fpm.conf)
├─ php-fpm: pool www (worker 1)
├─ php-fpm: pool www (worker 2)
├─ php-fpm: pool www (worker 3)
...
# ps aux | grep php-fpm 可見
三種進程管理策略(pm)
- static:固定
pm.max_children 個 Worker,適合高併發、記憶體充足、追求極致效能。
- dynamic:
pm.start_servers 啟動,根據閒置數量動態調整(pm.min_spare_servers ~ pm.max_spare_servers),適合一般場景。
- ondemand:無請求時 0 Worker,有請求才 fork,適合低流量、記憶體受限、容器化環境。
為什麼生產環境首選 PHP-FPM + Nginx?
- 進程隔離:PHP 崩潰不影響 Nginx,Master 秒級拉起新 Worker。
- 資源復用:OPcache、DB 連線池、Redis 連線池在 Worker 生命週期內復用。
- 運維友好:平滑重啟、慢日誌、狀態監控、權限隔離、多池隔離(不同站點不同 pool)。
- 擴充彈性:Worker 可部署在獨立伺服器(TCP Socket),支援水平擴展。
常見調優參數速查
; php-fpm.conf / www.conf 關鍵參數
pm = dynamic
pm.max_children = 100 # 最大進程數 = 記憶體 / 單進程記憶體 (留 20% 給系統)
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 1000 # 處理 1000 請求後重生,防記憶體洩漏
request_slowlog_timeout = 5s # 慢請求閾值
slowlog = /var/log/php-fpm/www-slow.log
rlimit_files = 65535 # 打開檔案數限制
rlimit_core = 0 # 禁止 core dump
security.limit_extensions = .php .phtml
總結
CGI/FastCGI 是**協議**;PHP-CGI/PHP-FPM 是**實現協議的程式**。**PHP-FPM 是生產環境管理 PHP FastCGI 進程的事實標準**,提供進程池、平滑重啟、監控、隔離等企業級能力。Nginx + PHP-FPM(Unix Socket)是當前高效能 PHP 部署的黃金組合。理解協議與進程模型,能讓你在架構選型、故障排查、效能調優時游刃有餘。