首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

排查 PHP 進程過多佔用大量記憶體導致伺服器卡頓問題

     編輯:PHP 綜合知識

問題現象

某 KVM 虛擬機器配置監控時發現系統明顯卡頓,操作回應緩慢。初步懷疑網路或 CPU 瓶頸,經排查後鎖定為 PHP-CGI 進程數量異常暴增,耗盡記憶體資源。

排查步驟與證據

1. 排除網路瓶頸

sar -n DEV 2 10

網卡流量監控

網卡流量極低,排除網路擁塞或攻擊流量。

2. 檢查 CPU 負載

top

top 指令輸出

CPU 使用率不高,但發現大量 php-cgi 進程佔據進程表,記憶體佔用極高。

根因分析

  • PHP-FPM / php-cgi 採用 靜態進程池 或 動態進程池配置不當,pm.max_children 設定過大,或 pm.max_requests 為 0 導致進程不回收,記憶體洩漏累積。
  • 應用程式存在記憶體洩漏(如未釋放大型陣列、資料庫連線未關閉、循環引用未清理),導致單進程記憶體持續增長。
  • 請求處理緩慢(資料庫慢查詢、外部 API 超時),導致進程長期佔用,觸發動態池不斷產生新進程。

解決方案

1. 優化 PHP-FPM 進程池配置

; /usr/local/php/etc/php-fpm.d/www.conf
pm = dynamic
pm.max_children = 50          # 依記憶體計算:(總記憶體 - 系統/資料庫) / 單進程記憶體
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500         # 強制進程處理 500 次請求後重生,防洩漏
request_terminate_timeout = 30s
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log

2. 啟用 OPcache 並調整記憶體

; php.ini
zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1

3. 程式碼層面排查記憶體洩漏

  • 使用 memory_get_usage() 記錄關鍵節點記憶體變化。
  • 檢查大型資料集處理是否使用生成器、分批處理。
  • 確保資料庫連線使用持久連線或正確關閉、PDO 設定 ATTR_PERSISTENT = false。
  • 排查 Composer 自動載入、框架快取是否導致類重複載入。

4. 監控與告警機制

# 簡易監控腳本,每分鐘檢查 php-fpm 進程數與記憶體
#!/bin/bash
MAX_PROCS=60
MAX_MEM_PCT=85
CURRENT_PROCS=$(pgrep -c php-fpm)
MEM_PCT=$(free | awk '/Mem/{printf "%.0f", $3/$2*100}')
if [ $CURRENT_PROCS -gt $MAX_PROCS ] || [ $MEM_PCT -gt $MAX_MEM_PCT ]; then
    echo "$(date) ALERT: php-fpm processes=$CURRENT_PROCS mem=$MEM_PCT%" >> /var/log/php-fpm/monitor.log
    systemctl reload php-fpm
fi

加入 crontab -e:* * * * * /bin/bash /usr/local/bin/php-fpm-monitor.sh

驗證成效

調整後觀察 top、free -h、pmap -x PID,確認:

  • php-fpm 進程數穩定在預期範圍內。
  • 單進程記憶體佔用穩定,無持續增長趨勢。
  • 系統可用記憶體充足,負載正常,回應速度恢復。

預防建議

  1. 新專案上線前進行壓力測試,驗證進程池參數。
  2. 定期檢視 slow.log 優化慢查詢與慢請求。
  3. 採用 PHP 7.4+ 享受更好的記憶體管理與效能。
  4. 容器化部署時設定 memory_limit、cpus 限制,防止單容器拖垮宿主機。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved