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

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

CPU 使用率不高,但發現大量 php-cgi 進程佔據進程表,記憶體佔用極高。
pm.max_children 設定過大,或 pm.max_requests 為 0 導致進程不回收,記憶體洩漏累積。; /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
; 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
memory_get_usage() 記錄關鍵節點記憶體變化。ATTR_PERSISTENT = false。# 簡易監控腳本,每分鐘檢查 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,確認:
slow.log 優化慢查詢與慢請求。memory_limit、cpus 限制,防止單容器拖垮宿主機。