大量 TCP 连接导致 CPU 负载巨大

大量 TCP 连接导致 CPU 负载巨大

在大量 TCP 连接的情况下,某个 CPU 核心总会达到 100%,之后整个 VM 就会开始卡顿,丢包现象会比较明显。

有没有办法解决这个问题,让 TCP 连接使用更少的 CPU,甚至限制其速率?

注意:通过 iptables 进行速率限制不起作用。尝试了以下方法:

iptables -A INPUT -i eth0 -m state --state NEW -p tcp -m limit --limit 30/minute --dport 25565 -j ACCEPT

iptables -A INPUT -i eth0 -m state --state NEW -p tcp --dport 25565 -j DROP

请注意,即使删除端口也iptables -A INPUT -p tcp --dport 25565 -j DROP不起作用。

在 htop 下,我看不到哪个进程占用了 CPU,所以我猜想这是内核的问题。一些托管服务提供商(如 OVH)已经解决了这个问题,但在许多其他托管服务提供商下,这种情况仍然会发生。我有什么选择?

此致

答案1

我认为您的问题不在于内核,也不认为您的计算瓶颈与您的网络有关,这取决于您的硬件。

我做了以下实验:

服务器计算机 1:使用 hping3 以每秒 28,870 个的速率(通过实验得出,并且认为与您正在执行的操作足够接近)生成 SYN 数据包到服务器计算机 2 上的端口 25565。使用的命令:

$ sudo /usr/sbin/hping3 -p 25565 --syn --interval u20 s19

其中“s19”是服务器计算机 2,“u20”有开销,实际结果是每秒 28,870 个数据包,而不是 50,000 个。

服务器计算机2:有一个 iptables DROP 规则。还运行了 Turbostat 来观察电源和 CPU 负载。运行了以下命令:

doug@s19:~/tmp$ sudo iptables -xvnL ; sleep 10 ; sudo iptables -xvnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination
 2293479 91739160 DROP       tcp  --  br0    *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:25565

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination
 2582175 103287000 DROP       tcp  --  br0    *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:25565

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination

因此 10 秒内有 2582175 - 2293479 = 288,696 个数据包,即每秒 28,870 个。注意:我的每个数据包的字节数确实比您的少,只有 40,而您的似乎有 60。

$ sudo turbostat --Summary --quiet --show Busy%,Bzy_MHz,IRQ,PkgWatt,PkgTmp,RAMWatt,GFXWatt,CorWatt --interval 6
Busy%   Bzy_MHz IRQ     PkgTmp  PkgWatt CorWatt GFXWatt RAMWatt
0.61    4800    196262  38      17.91   17.25   0.00    0.89
0.61    4800    196844  38      17.95   17.29   0.00    0.89
0.60    4800    197409  39      18.01   17.35   0.00    0.89

CPU 利用率可以忽略不计,但比空闲时多用大约 16 瓦(空闲 = 1.5 瓦)。

台式电脑1:qemu/kvm 虚拟机 20.04 作为客户机在服务器计算机 2 上运行。

服务器计算机1的hping3命令变成:

$ sudo /usr/sbin/hping3 -p 25565 --syn --interval u20 192.168.111.19

结果是:

doug@desk-ff:~$ sudo iptables -xvnL ; sleep 100 ; sudo iptables -xvnL
Chain INPUT (policy ACCEPT 117 packets, 9384 bytes)
    pkts      bytes target     prot opt in     out     source               destination
 2086906 83476240 DROP       tcp  --  enp1s0 *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:25565

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 73 packets, 9116 bytes)
    pkts      bytes target     prot opt in     out     source               destination
Chain INPUT (policy ACCEPT 144 packets, 12151 bytes)
    pkts      bytes target     prot opt in     out     source               destination
 4970267 198810680 DROP       tcp  --  enp1s0 *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:25565

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 77 packets, 9996 bytes)
    pkts      bytes target     prot opt in     out     source               destination

因此,100 秒内有 4970267 - 2086906 = 288,361 个数据包,即每秒 28,834 个。

在主机上:

$ sudo turbostat --Summary --quiet --show Busy%,Bzy_MHz,IRQ,PkgWatt,PkgTmp,RAMWatt,GFXWatt,CorWatt --interval 6
Busy%   Bzy_MHz IRQ     PkgTmp  PkgWatt CorWatt GFXWatt RAMWatt
9.61    4800    207685  58      31.19   30.53   0.00    0.89
9.64    4800    211088  58      31.14   30.48   0.00    0.89
9.44    4800    202499  59      30.72   30.07   0.00    0.89

我有 12 个 CPU,因此利用率大于 1 个 CPU 的 100%。或者通过 top:

top - 11:58:16 up 10 days, 18:57,  2 users,  load average: 1.00, 0.99, 0.81
Tasks: 239 total,   1 running, 238 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.3 us,  0.0 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu5  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu8  :  0.0 us,  0.0 sy,  0.0 ni, 98.3 id,  0.0 wa,  0.0 hi,  1.7 si,  0.0 st
%Cpu9  :  0.0 us,  3.1 sy,  0.0 ni, 95.6 id,  0.0 wa,  0.0 hi,  1.4 si,  0.0 st
%Cpu10 :  8.3 us, 90.3 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  1.3 si,  0.0 st
%Cpu11 :  0.0 us,  0.0 sy,  0.0 ni, 98.3 id,  0.0 wa,  0.0 hi,  1.7 si,  0.0 st

因此,是的,在虚拟机中执行此操作似乎会消耗更多 CPU 资源。一种选择是不要在虚拟机中执行此操作。或者,为虚拟机分配更多 VCPU。我能够达到每秒 118,283 个数据包(“u1”hping3 间隔选项),而主机上的整体 CPU 利用率仅增加了几个百分点。

编辑:主机处理器利用率与每秒发送到虚拟机的数据包数量的关系相当有趣,其阶跃函数类型响应在 5000 到 6000 pps 之间(回想一下,对于这个 12 CPU 主机,8.33% 是 1 CPU 的 100%):

在此处输入图片描述

相关内容