現象描述
Windows + IIS + PHP (FastCGI) 環境中,任務管理員顯示大量 php-cgi.exe 進程,CPU 長期佔用 100%,網站回應緩慢或掛起。
根因分析
- FastCGI 進程池設定過大: PHP 設定檔
php.ini 或 FastCGI 應用程式集區設定中 InstanceMaxRequests、MaxInstances (或舊版 StartProcesses) 設定過高 (如 6、10 甚至更大),導致同時啟動過多 php-cgi 進程搶佔 CPU。
- 程式碼效能問題: 應用程式存在死迴圈、未優化 SQL 查詢、大量檔案 I/O、遞迴無終止條件等,單一請求耗盡 CPU,進程池持續滿載。
- 系統臨時檔案爆炸: MySQL
tmpdir、PHP upload_tmp_dir、Windows TEMP 指向系統盤,累積數十萬小檔導致檔案系統效能驟降,間接拖垮 PHP 進程。
- 惡意攻擊/爬蟲: 大量並發請求觸發進程池擴容至上限,耗盡資源。
解決與優化方案
1. 調整 FastCGI 進程池參數 (立即見效)
- IIS 管理員 → 目標網站 → FastCGI 設定 → 編輯
php-cgi.exe 應用程式。
- 關鍵參數建議值 (視 CPU 核心數/記憶體調整):
| 參數 | 建議值 | 說明 |
| InstanceMaxRequests | 10000 | 單進程處理請求數達上限後回收,防記憶體洩漏 |
| MaxInstances / MaxProcesses | CPU核心數 × 2 ~ 4 | 例如 4 核心設 8-16,避免過多進程上下文切換 |
| ActivityTimeout | 300 | 閒置 5 分鐘回收進程釋放記憶體 |
| RequestTimeout | 60-120 | 單請求超時保護,防死迴圈佔住進程 |
2. 檢查並清理系統臨時目錄
- 開啟
C:\Windows\Temp、C:\Users\<服務帳號>\AppData\Local\Temp、MySQL tmpdir 路徑。
- 若發現大量
*.tmp、session_*、mysql_* 小檔,停止相關服務後清理 (可用 del /q /s *.tmp 或第三方工具)。
- 將臨時目錄遷移至資料盤 (如
D:\Temp),並設定定期清理排程。
3. 程式碼層面優化 (根治)
- 啟用 PHP 慢日誌 (
slowlog、request_slowlog_timeout) 定位耗時腳本。
- 使用 Xdebug/Blackfire 分析效能熱點。
- 優化 SQL:加索引、避免 SELECT *、分頁優化、使用快取 (Redis/Memcached)。
- 檢查迴圈、遞迴、大量檔案讀寫邏輯。
4. 防護異常流量
- IIS 動態 IP 限制 (Dynamic IP Restrictions) 限制單 IP 併發/頻率。
- 部署 WAF (ModSecurity/商業 WAF) 攔截惡意爬蟲、CC 攻擊。
- 啟用 PHP
max_execution_time、memory_limit 硬性限制。
5. 架構升級建議 (長期)
- 改用 PHP-FPM (Linux) 或 IIS 7.5+ 內建 FastCGI 管理,進程管理更穩健。
- 引入反向代理快取 (Nginx/Varnish) 卸載靜態/半動態請求。
- 微服務化拆分高負載模組,獨立擴容。
快速排查清單
- 任務管理員確認 php-cgi.exe 進程數 vs MaxInstances 設定。
- 查看 PHP 慢日誌 / IIS 日誌 (sc-status 200 但 time-taken 高)。
- 磁碟 I/O 計數器 (Avg. Disk Queue Length) 是否持續 > 2。
- 網路流量是否有異常單一 IP 大量請求。