Linux系统UDP丢包
最近工作中遇到某个服务器应用程序 UDP 丢包,在排查过程中查阅了很多资料,总结出来这篇文章,供更多人参考。
在开始之前,我们先用一张图解释 linux 系统接收网络报文的过程。
1,首先网络报文通过物理网线发送到网卡;
2,网络驱动程序会把网络中的报文读出来放到 ring buffer 中,这个过程使用 DMA(Direct Memory Access),不需要 CPU 参与
内核从 ring buffer 中读取报文进行处理,执行 IP 和 TCP/UDP 层的逻辑;
3,最后把报文放到应用程序的 socket buffer 中;
4,应用程序从 socket buffer 中读取报文进行处理。
在接收 UDP 报文的过程中,图中任何一个过程都可能会主动或者被动地把报文丢弃,因此丢包可能发生在网卡和驱动,也可能发生在系统和应用。
之所以没有分析发送数据流程,一是因为发送流程和接收类似,只是方向相反;另外发送流程报文丢失的概率比接收小,只有在应用程序发送的报文速率大于内核和网卡处理速率时才会发生。
本篇文章假定机器只有一个名字为 eth0 的 interface,如果有多个 interface 或者 interface 的名字不是 eth0,请按照实际情况进行分析。
NOTE:文中出现的 RX(receive) 表示接收报文,TX(transmit) 表示发送报文。
确认有 UDP 丢包发生
要查看网卡是否有丢包,可以使用 ethtool -S eth0 查看,在输出中查找 bad 或者 drop 对应的字段是否有数据,在正常情况下,这些字段对应的数字应该都是 0。如果看到对应的数字在不断增长,就说明网卡有丢包。
另外一个查看网卡丢包数据的命令是 ifconfig,它的输出中会有 RX(receive 接收报文)和 TX(transmit 发送报文)的统计数据:
~# ifconfig eth0
…
RX packets 3553389376 bytes 2599862532475 (2.3 TiB)
RX errors 0 dropped 1353 overruns 0 frame 0
TX packets 3479495131 bytes 3205366800850 (2.9 TiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
…
此外,linux 系统也提供了各个网络协议的丢包信息,可以使用 netstat -s 命令查看,加上 --udp 可以只看 UDP 相关的报文数据:
[root@holodesk02 GOD]# netstat -s -u
IcmpMsg:
InType0: 3
InType3: 1719356
InType8: 13
InType11: 59
OutType0: 13
OutType3: 1737641
OutType8: 10
OutType11: 263
Udp:
517488890 packets received
2487375 packets to unknown port received.
47533568 packet receive errors
147264581 packets sent
12851135 receive buffer errors
0 send buffer errors
UdpLite:
IpExt:
OutMcastPkts: 696
InBcastPkts: 2373968
InOctets: 4954097451540
OutOctets: 5538322535160
OutMcastOctets: 79632
InBcastOctets: 934783053
InNoECTPkts: 5584838675
对于上面的输出,关注下面的信息来查看 UDP 丢包的情况:
(1)packet receive errors 不为空,并且在一直增长说明系统有 UDP 丢包
(2)packets to unknown port received 表示系统接收到的 UDP 报文所在的目标端口没有应用在监听,一般是服务没有启动导致的,并不会造成严重的问题
(3)receive buffer errors 表示因为 UDP 的接收缓存太小导致丢包的数量
NOTE: 并不是丢包数量不为零就有问题,对于 UDP 来说,如果有少量的丢包很可能是预期的行为,比如丢包率(丢包数量/接收报文数量)在万分之一甚至更低。
网卡或者驱动丢包
之前讲过,如果 ethtool -S eth0 中有 rx_***_errors 那么很可能是网卡有问题,导致系统丢包,需要联系服务器或者网卡供应商进行处理。

最低0.47元/天 解锁文章
806

被折叠的 条评论
为什么被折叠?



