昨晚和一位读者伴侣一起接头了一个问题:在一台多核 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。