【问题记录】进程调度导致 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. 发送的数据包频率过快(网络拥塞)
相关推荐
skywalk816329 分钟前
在FreeBSD 14.3上部署轻量级Linux jail环境 仅仅占用10M内存
linux·运维·服务器·虚拟机·轻量化·freebsd·jail
知南x31 分钟前
【STM32MP157 异核通信框架学习篇】(10)Linux下Remoteproc相关API (下)
linux·stm32·学习
Tipriest_33 分钟前
Linux 环境变量的添加与查看详解
linux·环境变量
牢七2 小时前
新linux
linux
HIT_Weston4 小时前
27、【Ubuntu】【远程开发】内网穿透:CA 签名
linux·运维·ubuntu
阿巴~阿巴~5 小时前
基于UDP协议的英汉翻译服务系统:从网络通信到字典查询的完整机制
linux·服务器·网络·网络协议·udp协议·套接字绑定·英汉翻译服务系统
阿巴~阿巴~5 小时前
简易回声服务器实现与网络测试指南
linux·服务器·网络·udp协议·网络测试·udp套接字编程
凡间客8 小时前
Ansible安装与入门
linux·运维·ansible
君以思为故8 小时前
认识Linux -- 进程概念
linux·服务器
_OP_CHEN8 小时前
Linux网络编程:(八)GCC/G++ 编译器完全指南:从编译原理到实战优化,手把手教你玩转 C/C++ 编译
linux·运维·c++·编译和链接·gcc/g++·编译优化·静态链接与动态链接