传输速率偏低时,先别急着找运营商或换网线,多数情况下问题出在系统层,升级网卡驱动、调整队列和中断绑定、按需修改内核TCP参数这三板斧能解决大部分场景。
从网卡开始查:驱动和队列先别急着换硬件
系统层面排查速率问题,最优先要看的是网卡当前的工作状态,很多人一遇到速率上不去,第一反应是重启交换机,其实在Linux系统里输入一条命令就能看到很多事情。
用 ethtool 确认实际协商速率,别只看系统托盘里显示的“已连接”,在终端执行 ethtool eth0,注意看 Speed 那一行的值,如果显示 100Mb/s,而你的网卡明明支持千兆,那问题就出在链路协商上,这里最容易踩的坑有两类:一是网线老化或质量不达标,导致两端设备降级协商;二是对端交换机端口被强制设成了百兆,行业共识认为,排查链路协商问题应该遵循“先对端、后本机、再中间链路”的顺序。
第二步是检查 Ring Buffer 和队列数设置,用 ethtool -g eth0 查看当前环形缓冲区大小,如果看到 RX 和 TX 的当前值远低于最大值,说明缓冲空间不够,突发流量一来就会丢包,直观表现就是传输速率波动大、峰值上不去,把缓冲调大的命令是 ethtool -G eth0 rx 4096 tx 4096(根据实际网卡型号取最大值),调大缓冲对大量小文件传输的场景尤其有效。
驱动版本老旧的典型症状
系统日志里频繁出现 NIC Link is Up 但速率异常,或者持续报 tx_timeout 错误,极大概率是网卡驱动和固件太老,尤其是 Intel 的 i350 系列和博通的 BCM57412 等数据中心网卡,旧驱动在 TCP Segmentation Offload(TSO)和 Generic Receive Offload(GRO)功能上存在不少已知问题,会导致 CPU 占用率不高但吞吐量受限。
更新驱动前先用 ethtool -i eth0 看当前版本,然后去网卡厂商官网对应型号页面查最新稳定版,操作路径:解压驱动包,进入 src 目录,依次执行 make 和 make install,重启后确认新驱动已加载,建议开启系统自动安全更新,避免因漏装补丁而踩坑。
传输速率偏低时别忽略中断和CPU亲和性
网卡硬件本身没问题,速率还是偏低,下一站就该查 CPU 中断处理,多队列网卡的每个队列都有专门的中断号,如果这些中断全部落在同一个 CPU 核心上,单核处理瓶颈会直接把吞吐量锁死。
查看中断分布的核心命令是 cat /proc/interrupts,重点看网卡对应的那几行数字,如果第二列(CPU0)的数字远大于其他列,确认是中断不均,此时需要做两件事:确认系统识别了网卡的多队列,以及把队列中断绑到不同核心上。

IRQ 绑定操作路径
先用 grep eth0 /proc/interrupts 找出网卡各队列的中断号,然后用 cat /proc/irq/<中断号>/smp_affinity 查看当前亲和性,并通过 echo 改变绑定关系,把 66 号中断绑到 CPU2,echo 4 > /proc/irq/66/smp_affinity(注意这里的值是 CPU 掩码,4 对应二进制 100,即第三个核心),绑定后做压力测试,观察 top 里各个 CPU 的软中断占用是否均匀。
现代系统已经比过去做得好很多。如果用的是支持 RPS(Receive Packet Steering)的内核,老网卡也能通过软件方式把收包处理分散到多个 CPU,开启方法:echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus,然后设置 rps_flow_cnt 为 4096 量级。
业内的普遍观点是,相比修改软件参数,优先使用硬件多队列+中断绑定的组合,CPU 开销更小、处理时延更低,如果你用的是 ESXi 或 KVM 虚拟机,可以通过参数配置将 VirtIO 网卡的多个队列分配给不同 vCPU,效果类似。
内核TCP参数调优:缓冲和窗口决定上限
传输速率上不去,还有个很隐蔽的原因:内核的 TCP 协议栈参数限制住了理论的带宽时延积,很多人只知道改 net.ipv4.tcp_congestion_control,但实际影响最大的是收发缓冲区大小和窗口缩放因子。
先用 sysctl net.ipv4.tcp_rmem 和 sysctl net.ipv4.tcp_wmem 看当前值,Linux 默认值对跨机房、跨地域的长肥网络(带宽高、时延也高)不够友好,比如从北京机房传到上海机房的专线场景中,带宽时延积很大,默认的收发缓冲会严重拖慢吞吐。
调优的推荐方向是把最大值放宽,并合理设置初始值,具体操作:编辑 /etc/sysctl.conf 写入以下配置:
net.ipv4.tcp_rmem = 4096 87380 16777216net.ipv4.tcp_wmem = 4096 65536 16777216net.core.rmem_max = 16777216net.core.wmem_max = 16777216
随后执行 sysctl -p 使配置生效,调整完这些参数后,配合 sar -n TCP,ETCP 1 观察重传率和连接数,如果重传率高于正常值,说明不是缓冲不够,而是链路存在丢包,需要回到物理层排查。
确认窗口缩放是否启用
net.ipv4.tcp_window_scaling 默认是开启的,但如果某些设备或中间网关禁用了它,TCP 窗口就无法突破 64KB 的上限,跨地域大带宽场景下,窗口不足会造成有效吞吐剧烈下降,检查方式是抓包看 TCP 握手的 SYN 包中是否带有 Window Scale 选项,如果两端均启用了而吞吐依旧低,需要确认中间链路设备没有改写该选项。

美团的专线场景和简米云上的 ECS 实例调法略有不同,云厂商一般默认已经把内核调优参数设置得较好,直接照搬网上教程可能出现反效果,但自建机房的物理服务器调整空间更大,值得精细化配置。
软中断和锁竞争:隐蔽的性能杀手
当速率问题是间歇性的,比如传输开始很快,几秒后突然掉到零,等一会儿又自动恢复,这类场景大概率是 CPU 的软中断堆积和内核锁竞争 引发的。
执行 cat /proc/softirqs 观察 NET_RX 的增长速度;再用 mpstat -I CPU 1 看单核软中断占用,如果发现单个 CPU 的 %soft 持续超过 60%而其他核心闲着,说明网卡中断或软中断处理有瓶颈,除了前面提到的 RPS 均衡外,还要检查新版本内核中 threaded interrupts 有没有被开启:cat /sys/class/net/eth0/threaded。
内核锁竞争问题在多队列网卡和高并发小包场景中尤其突出,直观表现是 CPU 占用不低但吞吐量无法提升,尤其是使用 veth 或者 OVS 网桥的容器环境(Docker 默认的 bridge 模式)。perf top 如果看到 spinlock 相关热点,建议查一下宿主机内核版本,较老的 3.x 内核在多核扩展性上存在劣势,升级到较新的 LTS 版本(如 5.10 或 6.1)往往有明显改善。
虚拟化环境的特有检查点
云服务器上传输速率偏低,和物理机的排查思路有交集,但侧重点不同,在 KVM 或 VMware 虚拟化环境里,半虚拟化网卡驱动是性能关键,如果确认是 VirtIO 网卡,先确认队列数量是否和 vCPU 匹配:ethtool -l eth0,厂商默认配置只开 1 个队列的情况非常普遍,而 Windows 和 Linux 虚拟机在默认参数下的处理能力差距较大。
对于服务器之间的数据拷贝,比如用 rsync 或 FTP 传输大文件时,速率的瓶颈并不总在网卡上。先跑一次 iperf3 排除应用层干扰,iperf3 能跑满带宽而 rsync 不行,问题出在磁盘 IO 或文件系统。
反过来,iperf3 本身速率就无法提升,考虑 MTU 设置,多数机房内网已经支持巨帧,把 MTU 从 1500 调到 9000 能显著降低 CPU 开销和分片处理压力,操作路径:ip link set dev eth0 mtu 9000,改完需要确认链路对端和中间交换机的 MTU 同样支持,不通的话会有更大问题。
排查速率的参考基准
| 场景 | 需要校验的命令 | 核心关注指标 |
|---|---|---|
| 物理机/千兆网卡 | ethtool eth0 | Speed 值是否 1000Mb/s |
| 多队列/高并发 | /proc/interrupts | 各 CPU 中断是否均衡 |
| 虚拟机/云主机 | ethtool -l eth0 | 队列数是否与 vCPU 匹配 |
| TCP 长肥网络 | sysctl tcp_rmem/wmem | 缓冲是否达到带宽时延积 |
| 应用层瓶颈 | iperf3 对比测试 | 绕过应用后的原始带宽 |
传输速率上不去怎么办:验证环节
改动完系统参数之后,验证和回滚同样重要。先把改动前的参数存一份备份,sysctl -a > /tmp/sysctl_before_tuning.txt,再动配置,然后是双向测速,用 iperf3 分别跑上行和下行,只测单向容易漏掉网卡 TX 或 RX 方向的独立问题:iperf3 -c <服务器IP> -R 测反向,测试时长建议跑 30 秒以上,取平均值并记录 PPS(包每秒),两者结合看才是完整性能画像。
最后的最终验证要看业务实际场景,如果你遇到的情况是“传输速率偏低且速率波动极大”,在排除系统层问题后仍然没有头绪,可以抓包看 TCP 重复确认(Dup ACK)的数量,确认是否存在中间链路的随机丢包,此时常规的系统调优已到边界,重点转向物理链路和交换机的端口统计查询交换机端口 discard 或 error 状态增长情况,不少 100G 环境中速率上不去的最终原因其实是光模块的接收功率不达标,这属于物理层和链路层的范畴,就不在系统层的排查范围里了。
系统层检查没有万能药,用 ethtool -S eth0 看收发包统计里的丢包计数,用 sar -n EDEV 1 观察网卡报错,都是快速定位的手段,按队列→中断→内核参数→虚拟化的顺序,结合存储和链路侧因素,多数速率偏低问题都能有明确结论。如果系统参数都已经是最优配置而速率依然受限,就该考虑升级链路带宽了。
疑问解答:关于传输速率偏低的系统层排查
传输速率偏低一定是系统层问题吗?
不完全是,系统层问题(驱动、队列、中断、TCP参数)确实是首要排查目标,但也需要同步关注物理链路质量(网线光模块)、对端设备协商状态以及应用本身的 IO 瓶颈,建议先用 iperf3 做裸吞吐测试,能在应用层之外确认系统层的真实能力边界,根据排查顺序,一般遵循“物理层→链路层→系统层→应用层”的流程。
传输速率偏低时,如何判断是中断不均还是TCP参数问题?
一个简单方法:观察问题时 CPU0 的软中断占用是否明显高于其他核心,如果是,优先处理中断绑定的问题;如果所有核心软中断占用都低,传输速率依旧不达标,那就是 TCP 缓冲区或窗口缩放限制的瓶颈。mpstat -P ALL 1 加 sar -n TCP 结合判断比较高效,前者侧重 CPU 视角,后者侧重协议栈视角。
