什么是丢包?
丢包(Packet Loss) 是计算机网络中数据包(Packet)在传输过程中未能到达目标地址的现象。数据包是网络通信的基本单元,包含信息内容及控制信息(如源地址、目标地址、校验码等)。丢包会导致通信质量下降,甚至影响业务正常运行。
核心概念
- 数据包的作用
- 数据在传输时会被拆分为多个数据包,每个包独立路由,最终在接收端重组为完整数据。
- 示例:下载文件时,文件被拆分成多个包传输,丢包会导致文件下载不完整。
- 丢包的表现
- 部分数据丢失:如视频通话卡顿、语音断续、文件传输失败等。
- 重传机制触发:可靠协议(如TCP)会因丢包重传数据,增加延迟。
丢包的类型
- 被动丢包(本章节主要讲此类型)
- 定义:因硬件故障、资源不足或配置错误导致非主动丢弃
- 典型场景:
- 缓冲区溢出:网卡接收队列(RX Ring)过小,数据包被丢弃
- 校验失败:CRC错误、IP/TCP校验和错误
- 主动丢包
- 定义:设备或者系统根据策略主动丢弃数据包
- 典型场景:
- QoS限速:路由器在拥塞时丢弃低优先级流量
- 安全防护:防火墙拦截DDoS攻击流量
如何判断服务器是否有丢包

- RX errors
表示总的收包的错误数量,这包括 too-long-frames 错误,Ring Buffer 溢出错误,crc 校验错误,帧同步错误,fifo overruns 以及 missed pkg 等等。
- RX dropped
表示数据包已经进入了 Ring Buffer,但是由于内存不够等系统原因,导致在拷贝到内存的过程中被丢弃。
- RX overruns
表示了 fifo 的 overruns,这是由于 Ring Buffer(aka Driver Queue) 传输的 IO 大于 kernel 能够处理的 IO 导致的,而 Ring Buffer 则是指在发起 IRQ 请求之前的那块 buffer。很明显,overruns 的增大意味着数据包没到 Ring Buffer 就被网卡物理层给丢弃了,而 CPU 无法即使的处理中断是造成 Ring Buffer 满的原因之一,上面那台有问题的机器就是因为 interruprs 分布的不均匀 (都压在 core0),没有做 affinity 而造成的丢包。
- RX frame
表示 misaligned 的 frames。
- 可以通过ethtool -S em1 查看网卡的计数器以判断详细的丢包类型

为什么会发生丢包
网卡接受数据包流程
- 网卡收到数据包。
- 将数据包从网卡硬件缓存转移到服务器内存中。
- 通知内核处理。
- 经过 TCP/IP 协议逐层处理。
- 应用程序通过 read() 从 socket buffer 读取数据

Linux 网络协议栈收消息过程-Ring Buffer
- 数据包到达网卡(NIC1)
- 网卡通过物理链路接收到数据包,传输至内存
- DMA传输到环形缓冲区(Ring Buffer)
- DMA(Direct Memory Access):网卡绕过CPU,直接通过硬件将数据包写入内存中的 环形缓冲区
- 触发硬中断(Hardware Interrupt)
- 网卡完成DMA传输后,向CPU发送 硬件中断信号,通知系统有数据待处理。
- 中断处理程序(NIC interrupt Handler)
- CPU响应中断,执行 中断处理程序
- 软中断(Softirt)和轮询队列处理
- 软中断触发:中断处理程序退出后,内核发起软中断(NET_RX_SOFTIRQ)
- 高层协议处理(Higher Layer Processing)
- 数据包进入TCP/IP协议栈,进行拆包、校验、路由等操作,最终交付给应用程序。

丢包发生原因和常见的一些解决手段
- Ring Buffer过小,CPU没有处理完数据包,新的数据包进入网卡后,Ring Buffer已经满了导致新的数据包被丢弃
- 查看Ring Buffer当前设置和硬件支持的最大值

- 修改Ring Buffer设置
ethtool -G em1 rx 4096
ethtool -G em1 tx 4096
- 注:Ring Buffer并不是越大越好,更大的Ring Buffer往往会增加服务延迟
- Ring Buffer已经设置网卡支持的最大值,但网卡队列设置的偏小,无法及时消费Buffer中的数据包导致的新数据包被丢弃
- 查看网卡队列当前设置和硬件支持的最大值

- 修改网卡队列设置
ethtool -L em1 combined 64
- Ring Buffer和网卡队列已经设置为网卡支持的最大值,但中断全部集中在某一个或几个CPU核心,无法及时消费Buffer中的数据包导致的新数据包被丢弃
- 查看CPU中断

- 查看网卡中断

- 查看 irqbalance.service是否启用

- 注:如果开启了irqbalance服务中断仍然不均匀的情况,建议将网卡队列和CPU核心进行中断绑定,由指定的CPU核心去处理指定的网卡中断,建议qps较高的业务进行设置
- Ring Buffer、队列、中断绑定和kernel参数设置均已经最优(网络设备无异常情况),仍然发生丢包的情况需要扩容集群