nginx-mqtt 负载不均衡排查过程
背景
8 core cpu
的服务器上运行 nginx
, 自动绑定了8 core
, 对 nginx
进行10w的压力测试,发现 8 core
的连接数负载不均衡,
例如: 1,3,5,8 的负载数分别达到了2w的连接数,其他 core
的负载数仅有300个连接数,什么原因导致的?如何进行修复?
在8核 CPU
服务器上运行 Nginx
时,如果发现连接数负载不均衡,可能是由以下原因导致的:
- CPU亲和性:
Nginx
工作进程可能没有均匀地分配到所有CPU核心上。 - Nginx配置:可能存在配置不当,例如
worker_processes
和worker_connections
设置不正确。 - 操作系统调度:操作系统的任务调度器可能没有将请求均匀地分配到所有核心。
- 请求模式:某些核心可能由于请求模式或流量特性而接收到更多的连接。
- 硬件问题:服务器硬件可能存在问题,导致某些核心性能不如其他核心。
- 软件限制:操作系统或
Nginx
的限制可能影响核心的连接数。
如何提高nginx 中某个worker的优先级
第一步:获取容器中的主进程号
ps -p $(docker inspect --format '{{.State.Pid}}' nginx-emqx)
PID TTY TIME CMD
22570 ? 00:00:00 nginx
第二步:获取对应的nginx: worker的进程号
ps l --ppid 22570|grep "[n]ginx: worker"|awk '{print $3}'
22693
22694
第三步:获取每个进程对应的连接数
sudo ls /proc/22693/fd|wc|awk '{print $1}'
20
sudo ls /proc/22694/fd|wc|awk '{print $1}'
26
第四步:调整某个进程的优先级
在第三步中获取的结果进行分析,选择具体需要调整的进程号,例如上面样例,我们选择22693进程,nice
的取值范围优先级范围从-20(最高优先级)到19(最低优先级),默认情况下,进程的优先级是0。
sudo renice -10 -p 22693
排查过程
- cpu 用户态优先级
cat /proc/stat
cpu指标 含义
user 用户态时间
nice 用户态时间(低优先级,nice>0)
cpu0 45403699 95 31452510 837282308 637113 0 16079092 0 0 0
cpu1 24583887 15 20865506 884163594 2123579 0 10194643 0 0 0
cpu2 44650037 94 31742554 836112527 1205688 0 18503891 0 0 0
cpu3 24185191 15 20804395 883717933 283835 0 11540771 0 0 0
cpu4 45492231 90 32239278 841800200 883537 0 11814814 0 0 0
cpu5 24961570 13 20929986 890246913 343772 0 4657818 0 0 0
cpu6 45430864 100 32374453 838885028 792347 0 14841219 0 0 0
cpu7 24566994 18 20768724 887474748 378774 0 6816822 0 0 0
- nginx 进程连接数
/home/nginx-cores.sh
#!/bin/sh
nginx_pids=`ps aux |grep "[n]ginx: worker"|awk '{print $1}'`
for pid in $nginx_pids
do
n=`ls /proc/$pid/fd |wc|awk '{print $1}'`
echo "pid = $pid $n connection"
done
docker exec -it nginx-mqtt sh /home/nginx-cores.sh
pid = 496 24159 connection
pid = 497 830 connection
pid = 498 423 connection
pid = 499 27400 connection
pid = 500 27467 connection
pid = 501 497 connection
pid = 502 1039 connection
pid = 503 25758 connection
- 查看进程在哪个
cpu
上
ps -eo pid,ppid,args,psr|grep 10924
#参数的含义:
pid - 进程ID
args - 该进程执行时传入的命令行参数
psr - 分配给进程的逻辑CPU
17994 10924 nginx: worker process 6
17995 10924 nginx: worker process 3
17996 10924 nginx: worker process 1
17997 10924 nginx: worker process 6
17998 10924 nginx: worker process 6
17999 10924 nginx: worker process 0
18000 10924 nginx: worker process 0
18001 10924 nginx: worker process 2
# 进程分配到cpu上,绑定关系会变动
17994 10924 nginx: worker process 5
17995 10924 nginx: worker process 6
17996 10924 nginx: worker process 2
17997 10924 nginx: worker process 5
17998 10924 nginx: worker process 2
17999 10924 nginx: worker process 0
18000 10924 nginx: worker process 6
18001 10924 nginx: worker process 5
- 进程与
cpu
的亲和性
wcq@iZbp1hftd4ce4kejfkufowZ:~$ taskset -p 17995
pid 17995's current affinity mask: ff
wcq@iZbp1hftd4ce4kejfkufowZ:~$ taskset -p 17994
pid 17994's current affinity mask: ff
wcq@iZbp1hftd4ce4kejfkufowZ:~$ taskset -p 17996
pid 17996's current affinity mask: ff
wcq@iZbp1hftd4ce4kejfkufowZ:~$ taskset -p 17997
pid 17997's current affinity mask: ff
wcq@iZbp1hftd4ce4kejfkufowZ:~$ taskset -p 17998
pid 17998's current affinity mask: ff
wcq@iZbp1hftd4ce4kejfkufowZ:~$ taskset -p 17999
pid 17999's current affinity mask: ff
wcq@iZbp1hftd4ce4kejfkufowZ:~$ taskset -p 18000
pid 18000's current affinity mask: ff
在此示例中,返回的关联性(以十六进制位掩码表示)对应于二进制格式的 11111111
,这意味着该进程可以在八个不同的 CPU
核心(从 0 到 7)中的任何一个上运行
- 指定进程绑定在cpu上
[root@master mqtt-lb-nginx]# taskset -p 0x11 17306
pid 17306's current affinity mask: ff
pid 17306's new affinity mask: 11
问题:每次设置一次亲和性, 其他进程绑定的 cpu
会变, 如何解决?
ISSUE
cpu
上各个进程的负载不均衡,如何解决?
-
提高进程优先级。
NI
-10 效果不明显 -
提高
cpu
优先级
。 操作系统调度器:Linux
内核的调度器会根据当前的系统负载和调度策略
动态地将进程分配到不同的CPU上。
-
每个
cpu
的最大fd: 65535
,当达到最大值时,如果负载均衡策略,又分配到该cpu
时,- 是否会出现
worker_connections are not enough
? - 重新分配到不同
cpu
?
测试结果: 负载均衡策略:
hash $remote_addr;
未重新分配新的cpu, 出现worker_connections are not enough
。 - 是否会出现