帮助中心 >
  关于独立服务器 >
  视频服务器带宽跑满但CPU没跑满?瓶颈可能在网卡中断上
视频服务器带宽跑满但CPU没跑满?瓶颈可能在网卡中断上
时间 : 2026-06-05 14:04:02
编辑 : Jtti

  视频服务器带宽已经跑到几百兆甚至上千兆了,网卡快冒烟了,但打开top一看,CPU使用率才百分之二三十,悠闲得很。服务器配置不低,带宽也够,但视频就是卡,用户就是骂。这时候大多数人会怀疑:是不是程序写得有问题?是不是内核参数没调好?是不是买的服务器有坑?都有可能。但有一个特别常见又特别容易被忽略的瓶颈——网卡中断。

  先搞明白一件事:CPU没跑满不代表它不忙

  很多人对CPU使用率的理解有个误区,觉得“CPU使用率才30%,说明它很闲”。这个想法在单核时代勉强说得通,但现在是多核时代了,情况完全不一样。

  CPU使用率30%,意思是100个CPU核心里有70个在摸鱼,30个在干活。但问题来了:如果你那30个干活的核被网卡中断给占满了,剩下70个核再闲也没用。因为网卡中断绑定死了那几个核,其他核帮不上忙。

  这就好比一个快递站有100个员工,但只有30个人有权限拆快递包裹,剩下的70个人只能眼睁睁看着包裹堆成山。你问站长“人手够不够”,他说“我们才用了三成的人力”,但真实情况是——能干活的那30个人已经累趴下了。

  所以不要只看整体的CPU使用率,要看“哪个核在忙”。单核打满100%,其他核都是0%,整体使用率才1%。但你的网络性能已经炸了。

  网卡中断到底是怎么回事?

  先简单科普一下中断是个什么东西。网卡收到数据包之后,不能直接把数据往内存里一扔就不管了,它得通知CPU来取。怎么通知呢?就是发一个“中断信号”——相当于网卡在CPU耳边喊一嗓子:“来活儿了,快来处理!”

  CPU听到这个中断信号,就得放下手里正在干的事情,跑去把网卡收到的数据包取出来,一层一层地解包、组装、交给应用程序。这就是中断处理的整个过程。

  问题出在哪儿呢?网卡速度太快了。一个万兆网卡,每秒能收到上百万个数据包。每个包都发一个中断的话,CPU会忙成什么样?它什么都不用干了,整天就在那儿响应中断、响应中断、响应中断。

  这就是所谓的“中断风暴”——CPU被网卡中断淹没了,根本没时间处理真正的业务逻辑。你的视频服务器看起来在拼命干活,实际上CPU大部分时间都在应付网卡的中断请求。

  中断亲和性:一个被严重忽视的参数

  现在你知道了,中断是会占用CPU时间的。那能不能让不同的网卡中断分散到不同的CPU核心上去处理呢?

  当然可以,这就是“中断亲和性”。通俗地说,就是你可以手动指定:网卡0的中断由CPU核心2处理,网卡1的中断由CPU核心3和4处理,等等。

  但很多服务器默认的配置是——所有网卡中断都跑到CPU核心0上去。结果就是你的核心0被中断折磨得死去活来,使用率100%,其他几十个核心在旁边看戏。

  怎么查?用cat /proc/interrupts看一眼就知道了。你会看到每一行是一个中断号,每一列是一个CPU核心,下面的数字是这个中断在该核心上的处理次数。如果你发现某个中断号下面的数字只集中在第一个核心上,那就是中断没做负载均衡。

  怎么改?可以用echo命令把中断号的smp_affinity改成你想要的CPU掩码。比如让中断47只跑在CPU2和CPU3上,就把/proc/irq/47/smp_affinity设置成0xC(二进制1100,表示第3和第4个核)。当然,这需要root权限。

  现在很多现代系统有irqbalance服务,可以自动做中断负载均衡。但这个服务有时候并不聪明——它可能不认识你的NUMA架构,把网卡中断分配到了远处的CPU核心上,导致性能更差。所以有些性能敏感的场景会把irqbalance关掉,自己手工绑核。

  更高级的玩法:RPS和RFS

  如果你觉得手动绑中断太麻烦,或者你的网卡硬件不支持多队列,还有软件层面的解决方案:RPS(Receive Packet Steering)和RFS(Receive Flow Steering)。

  RPS的意思是:收到数据包之后,不直接在当前CPU核心上处理完,而是把处理任务分配到其他核心上去。这样就能避免中断都挤在一个核心上。

  RFS更进一步:它不仅把包分配到其他核心,还会尽量让同一个数据流(比如同一个TCP连接)的包始终由同一个核心处理。这样做的好处是CPU缓存命中率高,性能更好。

  开启RPS的方法是在/sys/class/net/eth0/queues/rx-0/rps_cpus里写一个CPU掩码,告诉系统这个网卡队列的包可以由哪些核心来处理。你可以设置成所有核心都参与,比如ffff表示前16个核心。

  不过这招也有代价。把包从一个核心转发到另一个核心是有开销的,尤其是当你的系统已经接近性能极限的时候,这个转发开销可能会成为新的瓶颈。

  还有一个容易被忽略的点:PCIe带宽

  很多人排查到这个程度就停了,觉得差不多了。但我告诉你,还有一个更隐蔽的瓶颈——PCIe带宽。

  网卡插在PCIe插槽上,所有收到的数据都要经过PCIe总线才能被CPU读到内存里。如果你的服务器上插了多块万兆网卡,同时还有其他高速设备(比如NVMe SSD、GPU),PCIe通道可能就不够用了。

  举个例子:PCIe 3.0 x8的理论带宽大约是7.88GB/s,看起来很大对吧?但如果你有两块万兆网卡同时跑满,每块1.25GB/s,这就2.5GB/s了,再加上NVMe SSD读写、显卡的DMA传输,分分钟把PCIe带宽打满。

  PCIe带宽打满的现象是什么?网卡统计信息里能看到大量的“rx_missed_errors”,意思是因为总线太忙,网卡自己的缓存满了,新的数据包来不及搬到内存里,直接就被丢掉了。

  这种情况怎么排查?用lspci -vvv看网卡所在的PCIe链路信息,看看链路宽度和速度是不是达到了标称值。有时候你明明插在x16的插槽上,但实际只跑在x4模式——可能是没插紧,也可能是BIOS设置的问题。

  视频服务器的特殊性:小包多、中断多

  视频服务器的情况比其他类型的服务器更特殊,因为视频流通常是RTP/UDP传输,包很小。一个1080p的视频流,MTU通常是1500字节,但实际负载可能只有1200多字节。而且视频编码的帧率可能是30fps、60fps,每帧又切成多个包。算下来,每秒的包数量相当可观。

  包越小,同样带宽下需要处理的中断就越多。同样是1Gbps的流量,如果全是1500字节的大包,每秒大概8万个包;但如果全是64字节的小包,每秒接近200万个包。200万次中断,对CPU来说是毁灭性的打击。

  这就是为什么有些视频服务器在跑高清流的时候,明明带宽才用了300Mbps,CPU就开始飙高了——因为码率虽然不高,但包数量巨大。

  针对这种情况,有一个经典的优化手段:网卡聚合。把多块网卡绑成一个bond,用负载均衡模式(比如balance-rr或者802.3ad),让多块网卡分担流量。每块网卡有自己的中断队列,理论上可以把中断负载分散到更多的CPU核心上。

  总结:视频服务器带宽跑满但CPU很闲,这个问题迷惑性很强。很多人第一反应是“加带宽”,但带宽本来就用不完;或者“升级CPU”,但CPU根本没发力。真正的问题往往出在中断处理的路径上。要么是中断都挤在少数核心上,要么是PCIe总线被别的设备抢占了,要么是小包太多导致中断频率过高。

  排查的时候记住一个顺序:先看每个核心的使用率,再看中断的分布,然后看网卡的丢包统计,最后查PCIe链路状态。顺着这条链,十有八九能找到根因。下次再遇到这种“假性空闲”的情况,你知道该从哪儿下手了。

售前客服
JTTI-Selina
JTTI-Amano
JTTI-Ellis
JTTI-Defl
JTTI-Eom
JTTI-Coco
技术支持
JTTI-Noc
标题
电子邮件地址
类型
销售问题
销售问题
系统问题
售后问题
投诉与建议
市场合作
信息
验证码
提交