Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> 關於 Linux

PHP-CGI 進程 CPU 100% 根因分析與三層優化方案

編輯:關於 Linux

PHP-FPM 進程佔用 CPU 100% 導致 502 Bad Gateway、響應極慢,是高併發 PHP 應用的典型故障。本文從代碼層、配置層、架構層三個維度,系統性剖析根因並給出生產級解決方案。

PHP-FPM CPU 100% 排查流程圖

核心根因分類

類別典型特徵根因排查入口
代碼死循環/長耗時特定 URL 持續高 CPU死循環、遞歸無出口、大數據未分頁處理slowlog、xhprof、strace
阻塞式網絡調用所有進程高 CPU、網絡等待file_get_contents/curl 無超時、外部 API 響應慢slowlog、netstat、tcpdump
正則回溯災難特定輸入觸發 CPU 飆升惡意正則 + 惡意輸入(ReDoS)代碼審計、正則測試
無限掛載/包含啟動後漸漸升高include 循環、自動加載器缺陷strace -p PID
惡意代碼/挖礦無業務流量也高 CPUWebshell、挖礦腳本、反彈 Shell掃描 webshell、進程樹分析

第一層:代碼層修復(治本)

1. 禁用/替換無超時網絡調用

// ❌ 危險:無超時,卡死進程
$content = file_get_contents('https://api.example.com/data');

// ✅ 安全:流上下文設置超時
$ctx = stream_context_create([
    'http' => ['timeout' => 3]  // 3 秒超時
]);
$content = file_get_contents('https://api.example.com/data', 0, $ctx);

// ✅ 更強大:Guzzle/cURL 異步+超時+重試
$client = new GuzzleHttp\Client(['timeout' => 3.0]);
$response = $client->get('https://api.example.com/data');

2. 正則防禦

// 限制回溯次數 (PCRE 8.32+)
ini_set('pcre.backtrack_limit', 100000);
ini_set('pcre.recursion_limit', 100000);

// 避免嵌套量詞:(a+)+、(.*)* 等
// 使用具體字符類代替 .*

3. 啟用 slowlog 定位熱點

; php-fpm.conf / www.conf
request_slowlog_timeout = 5s          # 超過 5 秒記錄慢請求
slowlog = /usr/local/php/var/log/slow.log

# 分析慢日誌
grep -A 20 "script_filename" /usr/local/php/var/log/slow.log

第二層:配置層防護(治標)

1. 請求終止超時(關鍵參數)

; php-fpm.conf
; 默認 0s 表示關閉,必須設置!
request_terminate_timeout = 30s

; 進程管理模式優化
pm = dynamic
pm.max_children = 100
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 500          # 防止內存洩漏,定期回收進程
原理: request_terminate_timeout 是 FPM 進程管理器強制 kill 超時進程的保護網,防止單個請求佔用進程導致進程池耗盡。但這只能治標,長請求仍會消耗 CPU。

2. 禁用危險函數

; php.ini
disable_functions = exec,system,shell_exec,passthru,popen,proc_open,pcntl_exec,eval,assert

第三層:架構層重構(徹底解決)

問題類型架構解決方案技術棧示例
外部 API 調用慢異步隊列 + 消費者模式Laravel Queue + Redis/RabbitMQ, Swoole 協程
大數據計算/報表離線預計算 + 緩存Crontab + Redis/Memcached, ClickHouse
圖片/視頻處理對象存儲觸發異步處理OSS/S3 + 函數計算/消息隊列
高併發寫入寫入分離 + 批量提交Kafka + 批量消費入庫

緊急排查命令速查

# 1. 找出高 CPU 進程
top -H -p $(pgrep -d',' php-fpm)

# 2. 追蹤進程系統調用
strace -p PID -c
strace -p PID -f -o trace.log

# 3. 查看 PHP 執行堆棧
gdb -p PID -ex "bt" -batch

# 4. 檢查打開文件
ls -l /proc/PID/fd/

# 5. 網絡連接狀態
netstat -anp | grep PID

總結

PHP-CGI CPU 100% 的鐵律:**「無超時不調用外部資源,無限制不寫正則,無異步不做耗時任務」**。優先序:**代碼層修復(加超時、限回溯) → 配置層防護(request_terminate_timeout、max_requests) → 架構層重構(異步隊列、預計算)**。建立 slowlog 常態化分析機制,將故障發現從「用戶投訴」前移到「監控預警」。

Copyright © Windows教程網 All Rights Reserved