之前有分析 receive buffer errors,在公司的项目中同时还遇到了 packet reassembles failed报错,在该篇文章中将对该问题进行分析
一. Packet reassemble
- 当发送的UDP报文长度大于MTU大小时,IP层会将报文进行分片
- 当接收端收到分片后,会进行分片重组,生成一个完整的UDP报文
分片重组的过程由内核协议栈完成的,协议栈需要一个buffer来存储已经到达的分片,等待所有分片到达,再进行重组
如上图所示,在MTU=1500的情况下,一个length=3200的大包,将被拆分为3个小包进行发送
- 在接收方将会对小包进行重组
- 由于Ethernet的特性,在分片到达接收方时:
- 分片有可能乱序
- 任意分片也有可能丢失
二. 确认是否是packet reassembles failed 导致UDP丢包
packet reassembles failed导致丢包的前提是发送的报文是大于MTU的大包
在上一篇文章中有提到netstat -s
可以看到内核协议栈的计数信息:
#netstat -s
Ip:
1075974066 total packets received
0 forwarded
0 incoming packets discarded
137873343 incoming packets delivered
3803720 requests sent out
48 dropped because of missing route
1411 fragments dropped after timeout
1072078860 reassemblies required
133978164 packets reassembled ok
239741 packet reassembles failed
215 fragments received ok
1720 fragments created
fragments dropped after timeout
: 分片在reassemble buffer中超时后被丢弃的计数packet reassembles failed
: 报文重组失败计数。该值包含timeout的计数
三. packet reassembles failed原因分析
1. fragments dropped after timeout 场景
- IP 某个分片丢失,始终无法重组成一个完整的报文,在reassemble buffer中的其他分片就会一直滞留,直到timeout被丢弃
当系统中有大量的fragments dropped after timeout
计数的增长时,我们一般需要确认的是底层链路是否存在一定的丢包率
1.1 模拟timeout方法
# 服务端
iperf -s -i 1 -u -w 4M -l 32360
# 客户端
iperf -c 172.16.128.6 -i 1 -u -b 128M -l 32360 -t 1000 -P1
在压测的过程中的某个瞬间,将客户端机器 power reset掉,在接收端查看,确认是否有timeout计数增加。
1.2 协议栈代码
/*
* Oops, a fragment queue timed out. Kill it and send an ICMP reply.
*/
static void ip_expire(unsigned long arg)
{
...