昨晚和一位讀者伴侶一起接頭了一個問題:在一臺多核 CPU 的 Web
處事器上,存在負載不平衡問題,個中 CPU0 的負載明明高于其它 CPUx,進一法式查表白 PHP-FPM 的嫌疑很大。話說以前我曾經記錄過軟間斷導致過雷同的問題,可是本例中可以解除嫌疑。
讓我們在一臺四查
處事器上采樣闡明一下數據確認一下是否存在負載不平衡問題:
shell> mpstat -P ALL 1 10
CPU %usr %nice %sys %iowait %irq %soft ... %idle
all 17.57 0.03 1.78 0.00 0.35 0.23 ... 80.04
0 43.17 0.00 4.12 0.00 1.41 1.00 ... 50.30
1 9.80 0.00 0.81 0.00 0.00 0.00 ... 89.39
2 9.31 0.00 1.20 0.00 0.00 0.00 ... 89.49
3 7.94 0.10 0.80 0.00 0.00 0.00 ... 91.16
如上呼吁的寄義是每秒運行一次 mpstat,一共采樣 10 次,可以明明看出 CPU0 的空閑 idle 明明小于其它 CPUx,并且大部門都耗損在了用戶態 usr 上面。
再讓我們通過 pidstat 來確認一下是不是 PHP-FPM 導致的 CPU0 負載問題:
shell> pidstat | grep
php-fpm | awk '{print $(NF-1)}' | sort | uniq -c
157 0
34 1
34 2
32 3
可見分派給 CPU0 的 PHP-FPM 歷程比其他三個 CPUx 總和還要多。為什么大部門歷程被分派給了 CPU0?我模恍惚糊有一些印象是因為操縱系統偏幸利用 CPU0,但我臨時也沒找到理論上的按照,假如有人知道,貧苦匯報我。
問題總要辦理,既然 PHP-FPM 沒有雷同 Nginx 那樣 CPU 親緣性綁定的指令,那么我們可以通過 taskset 手動綁定 PHP-FPM 歷程到牢靠的 CPUx 來辦理問題:
#!/bin/bash
CPUS=$(grep -c CPU /proc/cpuinfo)
PIDS=$(ps aux | grep "
php-fpm[:] pool" | awk '{print $2}')
let i=0
for PID in $PIDS; do
CPU=$(echo "$i % $CPUS" | bc)
taskset -pc $CPU $PID
let i++
done
如上劇本運行后,讓我們再來看看各個 CPU 負載分派環境如何:
shell> mpstat -P ALL 1 10
CPU %usr %nice %sys %iowait %irq %soft ... %idle
all 15.73 0.03 1.61 0.00 0.20 0.23 ... 82.20
0 16.28 0.10 1.62 0.10 0.81 0.91 ... 80.18
1 16.16 0.10 1.51 0.00 0.00 0.10 ... 82.13
2 14.46 0.10 1.71 0.00 0.00 0.00 ... 83.73
3 15.95 0.00 1.71 0.00 0.00 0.00 ... 82.35
終于平均了,不外需要提醒的是,一旦 PHP-FPM 處理懲罰的請求數高出 max_requests 的配置,那么對應的歷程將自動重啟,先前的 taskset 配置也將失效,所覺得告終果,我們大概需要把 taskset 劇本添加到 CRON 設置中去,譬喻每分鐘自動配置一遍!
本文把 PHP-FPM 歷程平均分派給了 0,1,2,3 四個 CPU,實際操縱的時候可以更機動一些,好比前文我們提過,系統老是偏幸利用 CPU0,假如 CPU0 的負載已經很高了的話,那么我們不妨把 PHP-FPM 歷程平均分派給 1,,2,3 三個 CPU。