一、基本情况
1. 问题环境
设备1:10.0.0.158 设备2:10.0.0.151 网速:千兆
2. 测试方式
使用 iperf3 测试:协议udp 带宽60M 时长10分钟 设备2(client):./iperf3 -c 10.0.0.158 -i 1 -p 40000 -t 600 -u -b 60M 设备1(server):./iperf3 -s 10.0.0.158 -i 1 -p 40000 测试结果:
设备2(server):./iperf3 -s 10.0.0.151 -i 1 -p 40001 设备1(client):./iperf3 -c 10.0.0.151 -i 1 -p 40001 -t 600 -u -b 60M 测试结果
很明显,存在丢包问题。
二、调试过程
1. 测试中观察现象
c
cat /proc/net/snmp | grep Udp && sleep 10 && cat /proc/net/snmp | grep Udp
打印信息 参数说明:
c
InDatagrams:接收到的 UDP 数据报文总数。
NoPorts:没有找到匹配的端口号,即收到的 UDP 数据报文由于没有应用程序监听对应的端口而被丢弃的数量。
InErrors:由于各种原因(如校验和错误、资源问题等)接收到的但未能成功处理的 UDP 数据报文数量,包含RcvbufErrors、SndbufErrors、InCsumErrors
OutDatagrams:从本机发送出去的 UDP 数据报文总数。
RcvbufErrors:由于接收缓冲区(receive buffer)溢出或其他问题导致的接收错误次数。
SndbufErrors:由于发送缓冲区(send buffer)溢出或其他问题导致的发送错误次数。
InCsumErrors:收到的 UDP 数据报文校验和不正确的次数。校验和用于检测数据在传输过程中是否出现错误。
IgnoredMulti:被忽略的多播数据报文数量。这可能是因为系统没有加入相关的多播组,或者多播流量控制策略导致某些数据报被丢弃。
【结果分析】从这些数据可以看出,在 10 秒的时间内,UDP 数据报文的接收和发送活动是活跃的,有新的数据报文被接收和发送。同时,也有一定数量的数据报文由于错误被丢弃。可以看到:InErrors和RcvbufErrors增加了。
2. InErrors 和 RcvbufErrors
从上面的数据中可以看到:
c
InErrors(接收错误的数据报文数)初始值:74,933,10 秒后的值:75,490,增加量:557(10 秒内由于错误被丢弃的 UDP 数据报文数)
RcvbufErrors(接收缓冲区错误数)初始值:74,933,10 秒后的值:75,490,增加量:557(10 秒内由于接收缓冲区问题导致的错误数)
关于InErrors 和 RcvbufErrors的详细解释: InErrors 这个计数器增加是因为接收到了无法处理的 IP 数据报。错误的原因可能包括:无效的头部、无法识别的协议、校验和错误、TTL 过期等。对于 UDP,如果数据报由于校验和错误或目的端口没有监听而被丢弃,InErrors 也会增加。
RcvbufErrors 这个计数器记录了由于接收缓冲区(receive buffer)溢出导致的数据报丢失。当网络接口接收数据的速度超过了系统处理的速度,或者系统的接收缓冲区大小配置不当,就可能发生缓冲区溢出。RcvbufErrors 通常与接收端的资源管理有关,而不是数据报本身的问题。
初步分析:udp 出现了 RcvbufErrors 以及 InErrors, 说明出现了系统UDP队列溢出时丢弃 udp pkt。
3. 确认网卡缓冲区是否溢出
在Linux操作系统中,可以通过 netstat -i --udp 命令来诊断网卡缓冲区是否溢出,RX-DRP 列显示网卡丢失的数据包个数。 参数解释
c
Iface:网络接口的名称,这里是 eth0(有线接口)和 lo(本地回环接口)。
MTU:最大传输单元,即接口可以处理的最大数据包大小。
RX-OK:正确接收到的 UDP 数据包数量。
RX-ERR:接收时出错的 UDP 数据包数量,这里两者都是 0,表示没有接收错误。
RX-DRP:由于缺少套接字而丢弃的 UDP 数据包数量,这里两者都是 0。
RX-OVR:由于缓冲区溢出而丢失的 UDP 数据包数量,这里两者都是 0。
TX-OK:成功发送的 UDP 数据包数量。
TX-ERR:发送时出错的 UDP 数据包数量,这里两者都是 0,表示没有发送错误。
TX-DRP:由于策略原因(如防火墙规则)而被丢弃的 UDP 数据包数量,这里两者都是 0。
TX-OVR:由于缓冲区溢出而未能发送的 UDP 数据包数量,这里两者都是 0。
Flg:接口的标志,显示接口的状态和特性。
B 表示接口处于广播模式。
M 表示接口处于多点传送模式。
R 表示接口处于路由模式。
U 表示接口处于上行状态。
L 表示接口正在运行。
另外通过 ifstat 观察并未发现丢包时出现流量突发的情况 【结果分析】eth0 接口在网络通信中相对活跃,有大量的 UDP 数据包被接收和发送。没有错误、丢弃或溢出的数据包表明网卡运行正常。
4. 调整接收线程的策略
当前优先级 调整为实时线程
c
chrt -pr 99 7592
观察60s,结果如下:
【结果分析】修改为RR 99的子卡:InErrors RcvbufErrors 各增加 10 个,未修改的增加 2071 个。说明网卡接收网络包的数据明显要比软件处理的速度快,调整接收线程的优先级可以非常明显的降低丢包。
4. perf 数据分析
将线程调整为 RR 60 依据会看到持续的丢包现象,怀疑是被高优先级的线程抢占导致。
c
./perf sched record -p 2597
./perf script < 2597.txt
通过抓取信息可以看到,处理接收数据的进程在运行时,会经常被高优先级的任务进程打断。
三、总结
网络丢包的一些常见原因:
- 接收端处理时间过长(数据接收线程调度不及时)
- 发送的数据包过大
- 发送的数据包频率过快(网络拥塞)