萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 作業系統 >  >> Linux 教學

Linux php-cgi 進程 CPU 100% 故障排查與根治方案

線上 Nginx + PHP-FPM 環境中,php-cgi(或 php-fpm worker)進程佔用 CPU 100% 是常見故障。本文從日誌分析、配置調優、代碼層面根治三個維度,提供系統化解決路徑。

第一階段:現場保護與日誌定位

關鍵日誌路徑

  • 網站訪問日誌:/home/hosts_log/(按站點 ID 分目錄)
  • PHP-FPM 主日誌:/usr/local/php_fcgi/logs/php-fpm.log
  • 慢請求日誌:/usr/local/php_fcgi/logs/slow.log(需開啟 request_slowlog_timeout)

排查步驟

  1. 檢查是否被植入惡意腳本:日誌中出現可疑 eval(base64_decode(...))、ddos 關鍵字、大量異常 POST 請求 → 立即隔離機器、清理木馬、修復漏洞。
  2. 分析慢日誌定位函數:若 slow.log 大量記錄 file_get_contents()、curl_exec() 等外部請求函數耗時極長,說明業務代碼阻塞在等待下游響應。

第二階段:PHP-FPM 配置調優(治標)

核心參數:request_terminate_timeout(單位:秒,0 表示關閉)

; /usr/local/php/etc/php-fpm.conf
30s

作用:強制終止執行超時的請求,防止所有 worker 被長連接佔滿導致 502 Bad Gateway。
副作用:若並發高、下游慢,依然會頻繁觸發終止,吞吐率急劇下降。

第三階段:代碼層面根治(治本)

問題根源

file_get_contents() 默認無超時,且 PHP max_execution_time 在 CLI/FPM 模式下對流操作不生效。一旦目標服務器無響應,進程永久阻塞。

解決方案:使用 Stream Context 設置超時

<?php
$ctx = stream_context_create([
    'http' => [
        'timeout' => 3,  // 3 秒連接+讀取總超時
        'method'  => 'GET',
    ]
]);
$content = file_get_contents("https://api.example.com/data", 0, $ctx);
// 建議封裝為通用 http_get($url, $timeout=3) 函數
?>

替代方案:cURL 更可控

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => 2,
    CURLOPT_TIMEOUT        => 5,
    CURLOPT_SSL_VERIFYPEER => false, // 內網可關閉驗證
]);
$data = curl_exec($ch);
curl_close($ch);

其他常見誘因

  • DedeCMS 等 CMS 生成靜態頁:大量文件 IO + 模板渲染導致 CPU 飆升 → 建議異步隊列生成、限制並發數。
  • 無限循環/死遞歸:代碼邏輯錯誤 → 通過 strace -p PID 或 gdb 定位行號。
  • OpCache 配置不當:opcache.validate_timestamps=0 導致代碼更新不生效,誤觸發異常邏輯。

應急處理 SOP

  1. top -c 確認高 CPU 進程 PID
  2. strace -p PID 觀察系統調用(若卡在 poll/read 多為網絡等待)
  3. kill -9 PID 釋放 worker 槽位(FPM 會自動重生)
  4. 部署超時修復代碼、重載 FPM
  5. 事後複盤:補全監控告警(CPU、慢請求、502 率)

核心原則:配置兜底(request_terminate_timeout),代碼必須有超時(stream context / cURL),日誌要可查(slowlog),監控要及時。

copyright © 萬盛學電腦網 all rights reserved