【问题记录】进程调度导致 UDP 丢包问题分析

一、基本情况

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

通过抓取信息可以看到,处理接收数据的进程在运行时,会经常被高优先级的任务进程打断。


三、总结

网络丢包的一些常见原因:

  1. 接收端处理时间过长(数据接收线程调度不及时)
  2. 发送的数据包过大
  3. 发送的数据包频率过快(网络拥塞)
相关推荐
小糖学代码6 小时前
LLM系列:1.python入门:3.布尔型对象
linux·开发语言·python
shizhan_cloud6 小时前
Shell 函数的知识与实践
linux·运维
Deng8723473486 小时前
代码语法检查工具
linux·服务器·windows
霍夫曼8 小时前
UTC时间与本地时间转换问题
java·linux·服务器·前端·javascript
月熊9 小时前
在root无法通过登录界面进去时,通过原本的普通用户qiujian如何把它修改为自己指定的用户名
linux·运维·服务器
大江东去浪淘尽千古风流人物10 小时前
【DSP】向量化操作的误差来源分析及其经典解决方案
linux·运维·人工智能·算法·vr·dsp开发·mr
赖small强10 小时前
【Linux驱动开发】NOR Flash 技术原理与 Linux 系统应用全解析
linux·驱动开发·nor flash·芯片内执行
IT运维爱好者12 小时前
【Linux】LVM理论介绍、实战操作
linux·磁盘扩容·lvm
LEEE@FPGA12 小时前
ZYNQ MPSOC linux hello world
linux·运维·服务器
郝学胜-神的一滴12 小时前
Linux定时器编程:深入理解setitimer函数
linux·服务器·开发语言·c++·程序人生