Linux内核常见的丢包场景有哪些

目录

摘要 

1 收发包处理流程

2 硬件网卡相关

2.1 ring buffer满

2.2 利用 ntuple 保证关键业务

3 arp丢包

3.1 neighbor table overflow

3.2 unresolved drops

4 conntrack丢包:nf_conntrack: table full

5 udp接收buffer满

6 丢包定位

6.1 dropwatch 查看丢包

6.2 利用 iptables LOG 跟踪报文流程

6.3 利用 iptables 规则跟踪丢包

7 总结


摘要 

      一个数据包在网络中传输的过程中,是没法保证一定能被目的机接收到的。其中有各种各样的丢包原因,今天来学习一下数据包经过 linux 内核时常见的丢包场景。

1 收发包处理流程

        有必要再回顾下 linux 内核的收发包处理流程,才能更好的认清楚数据包所经过的环节。

        当网卡接收到报文时,将数据包 DMA 拷贝到 RingBuf 并触发一个硬中断。继而 cpu 开始执行对应的(硬)中断处理例程。在硬中断处理例程中,将数据包 list 放在了每 cpu 变量 poll_list 中,紧接着触发了一个收包软中断。对应 cpu 的软中断线程 ksoftirqd 处理网络包接收软中断( net_rx_action() ),将数据包从 RingBuf 中取出,协议栈层层处理,经网络层到传输层,数据包被放到 socket 的接收队列中。随后被应用层收取数据。

        同样的,在发送数据时,skb 也是经过协议栈层层处理。在网络层对 skb 克隆,填充路由项,依次流经 netfilter 框架的 local_out 、post_routing 点。在邻居子系统填充了 mac 地址,在网络设备子系统中将 skb 放到了发送队列 RingBuf 中。在网卡发送完成后,又会通过硬中断触发软中断,在软中断处理函数中进行 RingBuf 的清理。

        接下来进入丢包正题。

2 硬件网卡相关

2.1 ring buffer满

        一般物理网卡丢包时,可以通过 ethtool -S 看到相应的统计信息:

[root@centos ~]# ethtool -s eht0
NIC statistics:  rx_packets: 123456  tx_packets: 789012  rx_bytes: 123456789  tx_bytes: 987654321  rx_errors: 0  tx_errors: 0  tx_dropped: 0  ...rx_no_buffer_count : 0  

        如果发现 rx_no_buffer_count 一直在增长,基本上是因为接收的 RingBuf 满导致的丢包。当然问题的核心原因还是接收流量太大& cpu 处理慢,导致数据包积压造成了丢包。具体的,可能有以下几种场景:

a 硬中断分发不均

        通过 cat /proc/interrupts 来查看网卡的硬中断是否均衡,如果报文处理都集中在一个核上,那么很大可能会导致 cpu 处理不过来导致丢包。这种情况可以考虑关闭 irqbalance,使用 set_irq_affinity.sh 来进行手动绑核,使硬中断的分发更均匀。

[root@centos ~]# cat /proc/interruptsCPU0       CPU1       ...27:    6547137          0   PCI-MSI-edge      virtio0-input.028:          1          0   PCI-MSI-edge      virtio0-output.029:          1    5938591   PCI-MSI-edge      virtio0-input.130:          1          0   PCI-MSI-edge      virtio0-output.1

b 会话分发不均

        有时候发现硬中断已经是均衡的了,但网络流量触发的中断量级更大,并且集中在某几个核上面,这也是可能导致丢包的原因之一。对于支持多接收队列的网卡,通过 RSS 功能,根据数据包的某些字段(如源ip、目的ip、源端口、目的端口)将数据包哈希到不同的接收队列中,进而分发给不同的 cpu 进行处理。

        查看网卡是否支持多队列:

[root@centos ~]# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX:		0
TX:		0
Other:		0
Combined:	2  # 支持2个组合队列:既可作接收也可作发送
Current hardware settings:
RX:		0
TX:		0
Other:		0
Combined:	2
# 查看 udp 会话分发哈希关键字
[root@centos ~]# ethtool --show-ntuple eth0 rx-flow-hash udp4
UDP over IPV4 flows use these fields for computing Hash flow key:
IP SA
IP DA

通过 ethtool --config-ntuple 可以修改分发使用的哈希关键字。

c rps

        如果网卡不支持多队列,或者支持的多队列远远小于CPU核数(当然这两种情况都比较少见了)。linux内核提供了 rps 机制来进行软中断的负载均衡。比如可以通过 echo ff > /sys/class/net/eth0/queues/rx-0/rps_cpus 来指定某个接收队列负载均衡到哪几个核处理。当然由于通过软件进行模拟,相比硬中断均衡,性能会下降很多,一般没有特殊原因,不建议开启。

d 突发流量

        如果是间接性的突发流量导致丢包,可以通过 ethtool -g 来查看当前的 RingBuf 配置,并通过ethtool -G 命令加大 RingBuf 的 size,减少突发流量导致的丢包。

[root@centos ~]# ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX:		1024
RX Mini:	0
RX Jumbo:	0
TX:		1024
Current hardware settings:
RX:		1024
RX Mini:	0
RX Jumbo:	0
TX:		1024

2.2 利用 ntuple 保证关键业务

        有些情况下,需要保证控制报文高优先级进行处理,默认情况下,网卡无差别对待所有报文,通过 rss 技术来选择队列,无法区分控制报文。可以开启网卡的 ntuple 功能来实现,比如将 tcp 端口号为 23 的报文,定向到 queue 9,与此同时其他报文仍使用 rss 技术,并且设置为使用 8 个队列:

[root@centos ~]# ethtool -K eth0 ntuple on
[root@centos ~]# ethtool -U eth0 flow-type tcp4 dst-port 23 action 9
[root@centos ~]# ethtool -X eth0 equal 8

        当对相应的业务进行绑核处理后,tcp 的 23 端口即可以跟其他业务不冲突,保证其高优先级进行处理。当然这个方案依赖于底层网卡的实现,并不是所有网卡都支持的。

3 arp丢包

3.1 neighbor table overflow

        arp 比较常见的一个问题是 neighbor 表满了,内核会大量打印如下的消息:

[22181.923055] neighbour: arp_cache: neighbor table overflow!
[22181.923080] neighbour: arp_cache: neighbor table overflow!
[22181.923128] neighbour: arp_cache: neighbor table overflow!

        cat /proc/net/stat/arp_cache 也能看到大量的 table_fulls 统计:

[root@centos ~]# cat /proc/net/stat/arp_cache 
entries  allocs destroys hash_grows  lookups hits  res_failed  rcv_probes_mcast rcv_probes_ucast  periodic_gc_runs forced_gc_runs unresolved_discards table_fulls
00000002  0000000d 0000000d 00000000  00000515 00000089  00000015  00000000 00000000  00000267 000003a1 00000023 0000039c
00000002  0000001c 0000001a 00000000  00001675 00000374  00000093  00000000 00000000  000003bf 00000252 00000046 00000240

 主要原因跟arp的参数如下几个参数相关,将其改大到合适的值即可解决该问题:

# 保存在于ARP高速缓存中的最少层数,如果少于这个数,垃圾收集器将不会运行
[root@centos ~]# echo 1024 > /proc/sys/net/ipv4/neigh/default/gc_thresh1 
# 保存在 ARP 高速缓存中的最多的记录软限制。垃圾收集器在开始收集前,允许记录数超过这个数字 5 秒
[root@centos ~]# echo 2048 > /proc/sys/net/ipv4/neigh/default/gc_thresh2 
# 保存在 ARP 高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行
[root@centos ~]# echo 4096 > /proc/sys/net/ipv4/neigh/default/gc_thresh3

3.2 unresolved drops

        当发送报文时,如果还没解析到 arp,就会发送 arp 请求,并缓存相应的报文。当然这个缓存是有限制的,默认为 SK_WMEM_MAX(即与 net.core.wmem_default 相同)。当大量发送报文并且 arp 没解析到时,就可能超过 queue_len 导致丢包,cat /proc/net/stat/arp_cache 可以看到unresolved_discards 的统计:

[root@centos ~]# cat /proc/net/stat/arp_cache
entries  allocs destroys hash_grows  lookups hits  res_failed  rcv_probes_mcast rcv_probes_ucast  periodic_gc_runs forced_gc_runs unresolved_discards table_fulls
00000004  00000006 00000003 00000000  0000008f 00000018  00000000  00000000 00000000  00000031 00000000 00000000 00000000
00000004  00000005 00000004 00000000  00000184 0000003b  00000000  00000000 00000000  00000053 00000000 00000005 00000000

        可以通过调整 /proc/sys/net/ipv4/neigh/eth0/unres_qlen_bytes 参数来缓解该问题。

4 conntrack丢包:nf_conntrack: table full

        当连接数比较多的时候,可能遇到这个连接跟踪表满的错误。

[ 2306.529864] nf_conntrack: nf_conntrack: table full, dropping packet
[ 2370.529866] nf_conntrack: nf_conntrack: table full, dropping packet
[ 2383.059264] nf_conntrack: nf_conntrack: table full, dropping packet

        conntrack 有个最大表项数(/proc/sys/net/netfilter/nf_conntrack_max)限制来控制。当 conntrack 数目达到 nf_conntrack_max 后,就会尝试将一些未 assured 状态的 conntrack 提前老化掉,尝试8次,未找到合适的可以提前老化的表项,就直接进行丢包处理。

        出于性能的考虑,调大 nf_conntrack_max 的同时,一般也需要调整 nf_conntrack_buckets,建议 max/buckets 小于8 比较合适,这样即使被攻击了,也能快速的进行 early_drop。比如调整 max 到300万,buckets 最好也做相应的调整:

[root@centos ~]# echo 3000000 > /proc/sys/net/netfilter/nf_conntrack_max
[root@centos ~]# echo $((65536*)) > /proc/sys/net/netfilter/nf_conntrack_buckets

5 udp接收buffer满

        当一个快的 udp sender,会导致一个较慢的 udp receiver socket recv buffer 满,导致丢包。尤其是存在大量突发的报文时。通过 netstat 查看 receive buffer errors 的统计就可以获知是否存在这种情况:

[root@centos ~]# netstat -su
...
Udp:690124 packets received3919 packets to unknown port received.0 packet receive errors694556 packets sent0 receive buffer errors0 send buffer errors
UdpLite:
IpExt:InNoRoutes: 2InMcastPkts: 37301InOctets: 2711899731OutOctets: 2207144577InMcastOctets: 1342836InNoECTPkts: 14891803InECT1Pkts: 2339

        一般通过修改 /proc/sys/net/core/rmem_max,并且设置 SO_RCVBUF 选项来增加 socket buffer 可以缓解该问题。

6 丢包定位

6.1 dropwatch 查看丢包

        除了 tcpdump 抓包进行分析外,dropwatch 也是网络协议栈丢包检查利器。实现原理也比较清晰,在 net/core/drop_monitor.c 文件中,当 kfree_skb 被调用时,内核就会记录下来,并通过 netlink 来通知用户态的 dropwatch 来记录。使用起来也非常简单,可以看到所有调用 kfree_skb() 的地方都会被输出:

[root@centos ~]# dropwatch -l kas
Initalizing kallsyms db
dropwatch> start
Enabling monitoring...
Kernel monitoring activated.
Issue Ctrl-C to stop monitoring
1 drops at skb_queue_purge+18 (0xffffffffb4467eb8)
1 drops at icmp_rcv+125 (0xffffffffb4505a35)
1 drops at icmp_rcv+125 (0xffffffffb4505a35)
1 drops at icmp_rcv+125 (0xffffffffb4505a35)
^CGot a stop message
dropwatch> exit
Shutting down ...

6.2 利用 iptables LOG 跟踪报文流程

        有时候,可能会有多个路由出口,为了知道特定的报文是如何路由出去的,可以借助 iptables LOG 来进行跟踪(需要结合limit模块来做限速,避免输出过多)。如下可以看到 ping 包是通过eth0 接口出去的:

[root@centos ~]# iptables -I OUTPUT -m limit --limit 1/s -p icmp -j LOG[root@centos ~]# ping www.baidu.com
PING www.a.shifen.com (183.2.172.185) 56(84) bytes of data.
64 bytes from 183.2.172.185 (183.2.172.185): icmp_seq=1 ttl=52 time=5.87 ms
64 bytes from 183.2.172.185 (183.2.172.185): icmp_seq=2 ttl=52 time=5.03 ms
64 bytes from 183.2.172.185 (183.2.172.185): icmp_seq=3 ttl=52 time=5.17 ms
^C
--- www.a.shifen.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 5.039/5.362/5.875/0.371 ms
[root@centos ~]# [root@centos ~]# dmesg
...
[2648940.712804] IN= OUT=eth0 SRC=10.0.24.9 DST=169.254.128.3 LEN=28 TOS=0x00 PREC=0x00 TTL=64 ID=23349 PROTO=ICMP TYPE=0 CODE=0 ID=50280 SEQ=34390 
[2648943.189182] IN= OUT=eth0 SRC=10.0.24.9 DST=169.254.128.15 LEN=28 TOS=0x00 PREC=0x00 TTL=64 ID=62301 PROTO=ICMP TYPE=0 CODE=0 ID=36154 SEQ=45797 
[2648943.730672] IN= OUT=eth0 SRC=10.0.24.9 DST=169.254.128.3 LEN=28 TOS=0x00 PREC=0x00 TTL=64 ID=23451 PROTO=ICMP TYPE=0 CODE=0 ID=50284 SEQ=34394 

6.3 利用 iptables 规则跟踪丢包

        还记得 netfilter 框架的的 5 个hook点吗?

        从图中可以看到,接收到报文,路由前,路由后,发送报文,都可以在配置 iptables 规则来进行跟踪。先梳理清楚数据包经过的 hook 点,接着配置 iptables 规则,使得协议命中但不会产生具体的动作,比如对于 ipsec 协议,通过以下两条规则统计的报文数观察在 OUTPUT 之后到 POSTROUTING 之间的丢包个数:

[root@centos ~]# iptables -t mangle -I OUTPUT -p esp
[root@centos ~]# iptables -t mangle -I POSTROUTING -p esp

7 总结

        除了上面介绍的一些场景外,还有很多其他的场景,比如 ip 层分片重组导致的丢包、tc配置的丢包等等,这里不再一一举例来说明了。总的来说,多总结,多思考,善于使用 linux 内核提供给我们的工具,才能更好的排查问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/309525.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线程池与工厂模式

线程池 如果我们需要频繁的创建销毁线程,此时创建销毁线程的成本,就不能忽视了.因此就可以使用线程池.即,提前搞好一波线程,后续需要使用线程就直接从池子里拿一个即可.当线程不再使用,就放回池子里. 本来,是需要创建线程/销毁线程.现在是从池子里获取到现成的线程,并且把线程…

BackTrader 中文文档(十)

原文:www.backtrader.com/ 用户自定义佣金 原文:www.backtrader.com/docu/user-defined-commissions/commission-schemes-subclassing/ 重塑 CommInfo 对象到实际形式的最重要部分涉及: 保留原始的 CommissionInfo 类和行为 为轻松创建用户定…

前端三剑客 —— JavaScript (第六节)

目录 内容回顾 BOM编程 DOM编程* document对象 document对象的属性 document对象的方法 DOM对象节点 操作DOM对象内容 操作DOM对象的属性 --- DOM对象.属性名称 --- DOM对象[属性名称] --- 调用系统API (Application Program interface)&#…

行业模板|DataEase批发零售大屏模板推荐

DataEase开源数据可视化分析平台于2022年6月发布模板市场(https://templates-de.fit2cloud.com),并于2024年1月新增适用于DataEase v2版本的模板分类。模板市场旨在为DataEase用户提供专业、美观、拿来即用的大屏模板,方便用户根据…

2024 年江苏省职业院校技能大赛“区块链技术应用” 赛项赛卷(样卷)运维题解析一

运维题 环境: ubuntu20 fisco 2.8.0 前言 准备两台机子,并且可以能相互pin通 192.168.19.133 [M1-A] 192.168.19.137 [M2-B] 子任务 1-2-1: 搭建区块链系统并验证 基于给定服务器环境以及软件,搭建一条双机 1 机构 8 节点 1 群组的区块 链系统(默认端口开始[30300,2020…

最优算法100例之43-包含min函数的栈

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 题目描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数,在该栈中,调用min,push及pop的时间复杂…

idea 中运行spring boot 项目报 Command line is too long的解决办法。

Command line is too long 在这里选择edit configures 选择shrten command line , 选择 jar manifest 运行即可。

5G网络开通与调测ipv4

要求如下: 1. 勘站规划 1. 【重】首先观察NR频点,完成设备选型 2645--选择N41 3455--选择N78 4725--选择N79 设备选型如下:观察AAU的通道数,最大发射功率;选择N41的选型频段也要选41 2. …

04—常用方法和正则表达式

一、字符串 1.length 属性返回字符串的长度(字符数)。 2.在字符串中查找字符串 indexOf() 字符串使用 indexOf() 来定位字符串中某一个指定的字符首次出现的位置 如果没找到对应的字符函数返回-1 lastIndexOf() 方法在字符串末尾开始查找字符串出现的位置。 3.replace() 方…

WordPress 图片压缩插件:Compress JPEG PNG images 使用方法

插件介绍 Compress JPEG & PNG images是一款非常好用的图片压缩插件:,非常值得大家安装使用;特别是图片类型网站。其实我们很多服务器磁盘空间是不在乎多那么几十 MB 大小的,但是压缩了图片能提升网站速度,节省宽带&#xff…

计算机本科毕业,「就业」还是「读研」?

如果本科不错能找到较好的工作,建议直接工作,否则可以选择读研。 如果你本科毕业于一所顶尖学府,且技术实力雄厚,那么直接就业可能更为明智;对比而言读研可以为你提供更多的时间和机会去提升自己,尤其是在…

算法1: 素数个数统计

统计n以内的素数个数 素数:只能被1和自身整除的自然数,0和1除外; 举例: 输入:100 输出:25 import java.util.*; class Test1{public static void main(String[] args){int a 100; //输入数字//…

智慧矿山视频智能监控与安全监管方案

一、行业背景 随着全球能源需求的日益增长,矿业行业作为国民经济的重要支柱,其发展日益受到广泛关注。然而,传统矿山管理模式的局限性逐渐显现,如生产安全、人员监管、风险预警等方面的问题日益突出。因此,智慧矿山智…

回归预测 | Matlab实现WOA-BP鲸鱼算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现WOA-BP鲸鱼算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现WOA-BP鲸鱼算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现WOA-BP鲸鱼算法优化BP神经网络多变量回归预测(完整源码…

文献阅读:Viv:在 web 上多尺度可视化高分辨率多重生物成像数据

文献介绍 「文献题目」 Viv: multiscale visualization of high-resolution multiplexed bioimaging data on the web 「研究团队」 Nils Gehlenborg(美国哈佛医学院) 「发表时间」 2022-05-11 「发表期刊」 Nature Methods 「影响因子」 47.9 「DOI…

计算机网络—传输层UDP协议:原理、应用

​ 🎬慕斯主页:修仙—别有洞天 ♈️今日夜电波:2月のセプテンバー 1:21━━━━━━️💟──────── 5:21 🔄 ◀️ ⏸ ▶️ ☰ &am…

RMT: Retentive Networks Meet Vision Transformers学习笔记

代码地址:GitHub - qhfan/RMT: (CVPR2024)RMT: Retentive Networks Meet Vision Transformer 论文地址:https://arxiv.org/pdf/2309.11523.pdf Transformer首次出现在自然语言处理领域,后来迁移到计算机视觉领域,在视觉任务中表现…

web3项目自动连接小狐狸以及小狐狸中的各种“地址”详解

刚做web3的时候,比较迷糊的就是人们口中说的各种地址,小狐狸钱包地址,私钥地址,跳转地址,接口地址,交易地址,等等XX地址,常常感觉跟做链的同事们说话不在一个频道。 这一小节&#x…

解锁生成式 AI 的力量:a16z 提供的 16 个企业指南

企业构建和采购生成式AI方面的16项改变 生成式 AI 领域趋势洞察:企业构建和采购生成式 AI 的方式正在发生重大转变,具体表现在:* 专注于可信度和安全性:75% 的企业将信任和安全性视为关键因素。* 优先考虑可扩展性和灵活性&#x…

YOLOv9/YOLOv8算法改进【NO.117】 使用Wasserstein Distance Loss改进小目标的检测效果

前 言 YOLO算法改进系列出到这,很多朋友问改进如何选择是最佳的,下面我就根据个人多年的写作发文章以及指导发文章的经验来看,按照优先顺序进行排序讲解YOLO算法改进方法的顺序选择。具体有需求的同学可以私信我沟通: 首推…