网络"时快时慢""偶尔超时""大文件传一半断了",很多情况下根子在丢包。丢包有个讨厌的地方:它不一定表现为完全不通,而是让 TCP 反复重传、应用响应忽快忽慢,用户体感是"网卡住了但又能用",排查时很容易误判成应用问题。要抓住它,必须从网卡自己的统计计数器开始。
这篇文章讲一套自下而上的网卡丢包排查方法:先读懂 ip -s link 的收发计数,区分丢包发生在发送侧还是接收侧;再用 ethtool 看驱动和链路层参数;然后向上延伸到交换机/云网络的排查;最后给出常见的调优项和风险提示。读完之后,你应该能从一堆计数器里迅速判断"包是在服务器里丢的,还是在服务器外的网络里丢的"。
需要明确一个前提:服务器侧能看到的丢包统计,只覆盖它自己网卡层面发生的事。如果丢包发生在中间的交换机、路由器或云网络上,服务器计数器往往是干净的,这时候要靠双向测试和抓包来推断。所以排查思路必须是"先分清责任边界"。
一、先读懂网卡的收发计数器
排查丢包第一步永远是看网卡统计,命令是 ip -s link(老命令是 ifconfig -a 或 netstat -i)。
# 查看指定网卡的详细统计
ip -s link show eth0
ip -s -s link show eth0 # 加第二个 -s 显示更详细的错误分类
# 实时观察计数变化(每 1 秒刷新,重点看哪些数字在涨)
watch -n 1 'ip -s link show eth0'
# 老命令(net-tools)
netstat -i
ifconfig eth0
ip -s -s link show eth0 的关键字段和含义:
| 字段 | 所在段 | 含义 | 异常含义 |
|---|---|---|---|
| RX packets | 接收 | 收到的包数 | 数量正常即可 |
| RX errors | 接收 | 接收错误总数 | 帧校验错、硬件问题 |
| RX dropped | 接收 | 接收侧丢弃 | 缓冲不足或协议栈丢弃 |
| RX overrun | 接收 | 环形缓冲溢出 | 收包太快,网卡来不及处理 |
| RX frame | 接收 | 帧对齐/长度错误 | 网线、双工、硬件 |
| TX packets | 发送 | 发送的包数 | — |
| TX errors | 发送 | 发送错误总数 | 硬件或链路问题 |
| TX dropped | 发送 | 发送侧丢弃 | 队列满、虚拟化环境常见 |
| TX carrier | 发送 | 载波错误 | 链路闪断、网线/光模块问题 |
| collisions | 发送 | 冲突计数 | 半双工环境下才有意义 |
判读的逻辑是:看哪个计数器在持续增长。用一个基线对比法最有效——先记录一次,等几分钟再记录一次,看增量。
# 采集两次样本对比增量
ip -s link show eth0 > /tmp/link1.txt
sleep 60
ip -s link show eth0 > /tmp/link2.txt
diff /tmp/link1.txt /tmp/link2.txt
如果 RX errors、RX dropped 在涨,说明接收侧有问题;如果 TX 的 dropped/carrier 在涨,说明发送侧有问题。分清方向是后续排查的分水岭。
二、发送侧丢包:多为队列和虚拟化问题
发送侧(TX)丢包在虚拟机和容器环境里尤其常见,原因往往是内核发包速度超过了底层能处理的速度。
# 查看发送队列长度和排队规则
ip -s link show eth0
tc -s qdisc show dev eth0
# 查看网卡驱动层的队列信息
ethtool -S eth0 | grep -iE 'tx|drop|queue'
# 查看队列满导致的丢弃统计
ethtool -S eth0 | grep -iE 'tx_errors|tx_dropped|tx_aborted'
发送侧丢包的常见原因:
- 发送队列太小或 qdisc 排队过多:高并发小包场景下,
tc的队列会积压。可用tc qdisc查看 backlog,必要时调整txqueuelen(ip link set eth0 txqueuelen 1000)。 - 虚拟化平台的 TX dropped 是正常现象:KVM/Xen 虚拟机的
TX dropped常常反映了宿主机的限流或半虚拟化网卡的处理能力,不一定代表故障。但持续大量增长要提高警惕。 - 网卡硬件队列不足:单队列网卡在多核高并发下容易成为瓶颈,可用
ethtool -l eth0查看队列数,支持多队列(RSS)的网卡可调大。
一个实用命令是 ethtool -S,它会输出驱动级别的所有计数器,不同驱动的字段名不一样,但常见的 tx_dropped、rx_missed_errors、rx_no_buffer_count 等含义相近:
# 列出驱动统计(不同网卡字段不同,grep 关键字)
ethtool -S eth0 | grep -iE 'drop|miss|error|no_buffer|fifo'
# 查看队列数量
ethtool -l eth0
ethtool -g eth0 # 查看环形缓冲区大小
三、接收侧丢包:先看环形缓冲与中断
接收侧(RX)丢包的根源通常是"包来得太快,内核处理不过来"。数据从网卡到内核要经过环形缓冲区(ring buffer)和中断处理,任何一环跟不上都会丢包。
# 查看环形缓冲区大小(当前值 vs 最大值)
ethtool -g eth0
# 临时调大环形缓冲区到最大值(可能提升接收能力,占用更多内存)
ethtool -G eth0 rx 4096 tx 4096
# 查看中断分布,判断是否所有中断都压在一个 CPU 上
cat /proc/interrupts | grep -i eth0
mpstat -P ALL 1 3 # 需 sysstat 包
# 查看软中断统计(NET_RX 过高说明网络收包压力大)
cat /proc/softirqs | grep -i net
典型的"接收丢包"案情:单队列网卡,所有网络中断都落到 CPU0,收包量大时 CPU0 被软中断打满,其他核闲着,ip -s link 的 RX dropped 持续增长。解决办法是启用多队列(RSS)并配合 irqbalance 或手动绑定中断到多个 CPU,或者用 RPS/RFS(多队列软件实现)。
# 查看是否启用了 RPS(软件多队列)
cat /sys/class/net/eth0/queues/rx-0/rps_cpus
# 例如设置为所有 CPU(十六进制掩码,0xf 表示 CPU0-3)
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus
# 安装并启用 irqbalance 自动分散中断
# RHEL/CentOS/Rocky
yum install -y irqbalance # 或 dnf
systemctl enable --now irqbalance
# Debian/Ubuntu
apt install -y irqbalance
systemctl enable --now irqbalance
环形缓冲、多队列、RPS 这些是接收侧调优的主要手段,但要注意:调大环形缓冲会增加内存占用和延迟,多队列需要网卡和驱动支持,调整前先确认硬件能力。
四、向上排查:交换机与云网络
如果服务器侧的 RX/TX 计数器都很干净,但业务确实在丢包,那么问题很可能在服务器之外的网络设备上,也可能是物理链路问题。
# 1. 物理层检查:网线、光模块、双工模式
ethtool eth0
# 关注 Speed(协商速率)、Duplex(全双工/半双工)、Link detected
# 2. 强制全双工(如果是双工不匹配导致大量 collisions)
# 注意:需要交换机侧同步设置,否则可能更糟
ethtool -s eth0 speed 1000 duplex full autoneg off
# 3. 链路错误统计
ethtool -S eth0 | grep -iE 'crc|align|fcs|carrier'
# 4. 网关丢包测试(判断丢包是本地还是上游)
ping -c 100 -i 0.2 192.168.1.1 # 打网关
mtr -rw -c 100 8.8.8.8 # 逐跳看丢包发生在哪一跳
# 5. 双向抓包对比(判断是发丢了还是收丢了)
tcpdump -i eth0 -n -c 100 host 203.0.113.10
关键判据:
ethtool eth0显示Duplex: Half(半双工),基本可以确定是双工不匹配,会导致大量冲突和丢包,必须两端统一为全双工。Speed协商成 100M 而链路应该是 1000M,说明网线质量差或接口问题,换线或换端口。ethtool -S里rx_crc_errors、rx_frame_errors持续增长,是物理链路问题(网线、光模块、接头)。mtr显示丢包从某一跳开始出现、且后续跳都丢,说明问题在那个节点或其后。- 抓包显示包发出去了但被对上收到的少了,说明中间网络丢包。
云服务器的情况要单独说:云厂商的网络在虚拟化层做了很多处理,tx_dropped 在新一代虚拟网卡上经常是常态(反映宿主限流),不一定是故障。云上排查丢包要结合:实例的带宽上限、突发积分是否耗尽、安全组是否有丢包策略、以及同可用区还是跨可用区(跨区延迟和丢包通常更高)。这些指标在云控制台的监控里能看到,比自己数计数器更准。
五、应用层视角:丢包如何影响业务
网卡丢包对上层的影响,取决于协议和丢包率。给出一些经验量级供参考(具体视业务而定):
| 丢包率 | TCP 表现 | 体感 |
|---|---|---|
| < 0.01% | 基本无感知,偶发重传 | 正常 |
| 0.1% | 少量重传,吞吐略降 | 大文件传输变慢 |
| 1% | 明显重传,吞吐大幅下降 | 网页加载变慢、偶发超时 |
| 5% | 频繁超时重传 | 视频卡顿、连接不稳定 |
| > 10% | 大量连接超时中断 | 基本不可用 |
TCP 对丢包很敏感,因为一次丢包往往触发拥塞窗口收缩。在高带宽高延迟链路上(BDP 大),1% 丢包就能让吞吐掉到理论值的零头。这也是为什么很多"带宽明明够,就是传不快"的案子,最后查到是丢包。
# 查看 TCP 重传统计
ss -s # 汇总信息
netstat -s | grep -iE 'retrans|timeout'
nstat -az | grep -iE 'Retrans|TCPTimeouts'
# 持续观察重传
watch -n 1 'netstat -s | grep -i retrans'
如果 netstat -s 里的 segments retransmitted 占比持续偏高,就说明链路正在丢包,值得往网络方向深挖。
六、调优建议与风险提示
# 查看/调整网卡参数
ethtool -k eth0 # 查看 offload 特性(校验和、TSO、GRO 等)
ethtool -K eth0 gro on # 调整 GRO
ethtool -K eth0 tso on
# 调整内核网络缓冲(/etc/sysctl.conf 或 /etc/sysctl.d/*.conf)
# net.core.rmem_max = 16777216
# net.core.wmem_max = 16777216
# net.core.netdev_max_backlog = 5000 # 接收队列积压上限
# net.ipv4.tcp_rmem = 4096 87380 16777216
# net.ipv4.tcp_wmem = 4096 65536 16777216
sysctl -p
风险提示与回滚:
ethtool -G调大环形缓冲会占用内核内存,可能挤压其他用途;改前记录原值(ethtool -g eth0),要回滚就用原值再设一次。ethtool -s强制速率/双工极其危险:如果交换机侧是自协商而服务器强制,会直接链路不通、服务器失联。远程服务器慎用,且必须两端同步。回滚方式是ethtool -s eth0 autoneg on恢复自协商。ethtool -K关闭 offload 有时能解决虚拟化下的奇怪问题,但要评估 CPU 开销,关闭 TSO/GRO 会显著增加 CPU 占用。- 修改
sysctl网络参数前先cp /etc/sysctl.conf /etc/sysctl.conf.bak,出问题还原后sysctl -p。
常见问题
Q:ip -s link 里 RX dropped 一直涨,但业务看起来正常,要紧吗?
要看丢的是什么包。如果丢的是广播、多播或不符合本机地址的包(比如混杂模式下的杂包),业务正常就无需处理。如果丢的是正常单播且量在涨,就要查环形缓冲、CPU 软中断和上层协议栈。
Q:怎么区分是服务器丢的包还是网络丢的包?
在服务器出口抓包(tcpdump -i eth0)记录发出的包数,在对端抓包记录收到的包数,两边一对比,差值就是中间网络丢的。服务器侧计数器干净、但对端收不全,责任就在网络。
Q:ethtool -S 输出字段太多看不懂,先看哪几个?
先 grep 这几类:drop、miss、error、buffer、fifo、crc。其中 rx_missed_errors、rx_no_buffer_count 指向接收缓冲不足,rx_crc_errors 指向物理链路,tx_dropped 指向发送队列或虚拟化限流。
Q:虚拟机上 TX dropped 一直在涨,是不是有问题?
在 KVM/Xen 等虚拟化环境下,TX dropped 很多时候反映的是宿主机侧的限流或半虚拟化网卡的处理策略,属于常见现象。要结合业务是否真的受损来判断;如果业务正常、延迟稳定,可以观察而不必处理。
Q:ping 大包丢、小包不丢,是丢包吗?
这通常是 MTU 或路径 MTU 的问题,不是传统意义的丢包。大包需要在中间设备分片或被丢弃,表现出来就是"小包能通、大包不通"。查 MTU 用 ping -M do -s 1472,具体方法见 MTU 相关主题。
总结
网卡丢包排查从 ip -s link(或 ip -s -s link)开始,先分清是接收侧丢还是发送侧丢,看哪个计数器在持续增长,这是整个排查的起点。
接收侧丢包多是环形缓冲不足、单队列 CPU 瓶颈、软中断打满,调优手段是 ethtool -G 调大 ring buffer、启用多队列与 irqbalance、配置 RPS。
发送侧丢包在虚拟化环境常见,先看 txqueuelen、qdisc backlog 和 ethtool -S 的 tx 类计数,不要一看到 TX dropped 就当成故障。
服务器计数器干净但业务在丢包时,向网络侧排查:用 ethtool 查双工/速率/CRC,用 mtr 定位丢包跳数,用双向抓包判断责任边界;云上还要结合带宽上限和突发积分看。
丢包对 TCP 影响很大,用 netstat -s/ss -s 看重传率评估影响;所有调优操作(尤其 ethtool -s 强制速率双工)都要先记录原值、评估风险、准备回滚,远程服务器慎改链路参数。
企业QQ咨询




