内容简介:我们内部基于dpdk自研的高性能负载均衡器dpvs已经在多个机房部署上线,运行正常,但近期有多个金融相关的业务反馈,服务数据包在经过dpvs转发后,会出现hang住的情况。dpvs已经在多个机房上线,运行时间已超过半年,为何突然有业务反馈异常反馈问题的业务多与金融区相关(金融区由于其特殊性,会额外增加安全方面的加固策略)为什么问题表现均为服务hang住
背景
我们内部基于dpdk自研的高性能负载均衡器dpvs已经在多个机房部署上线,运行正常,但近期有多个金融相关的业务反馈,服务数据包在经过dpvs转发后,会出现hang住的情况。
问题
dpvs已经在多个机房上线,运行时间已超过半年,为何突然有业务反馈异常反馈问题的业务多与金融区相关(金融区由于其特殊性,会额外增加安全方面的加固策略)为什么问题表现均为服务hang住
问题排查
首先,我们怀疑与dpvs或与金融的某些安全策略相关,因此我们做了如下测试(后端上跑的均是相同的测试代码,并模拟了服务端逻辑):
client < ----- > dpvs < ----- > rs(金融区) 不正常
client < ----- > dpvs < ----- > rs(非金融区) 正常
client < ----- > lvs < ----- > rs(金融区) 正常
client < ----- > lvs < ----- > rs(非金融区) 正常
通过1、2组测试能够得出结论:该问题与金融区相关且dpvs转发正常
通过3、4组测试能够得出结论:该问题与金融区无关且kernel版lvs转发正常
通过1、3组测试能够得出结论:该问题与dpvs有关,经过dpvs的请求不正常
通过2、4组测试能够得出结论:该问题与dpvs/lvs无关,经过dpvs/lvs的请求均正常
以上4组结论两两冲突,无法定位问题是与dpvs相关还是与金融区相关,排查一度进入僵局,无法定位故障点。
为了进一步排查,我们在client和后端rs上抓包排查,发现client的请求均能够正常到达rs,而rs的大部分数据也能够正常回复给client,但有固定的几个包总是会被重传且直至超时,以下是抓包截图:
其中10.128.x.x是rs的ip,10.115.x.0/24是dpvs的local ip,通过在rs上的抓包结果可以清楚的看出rs发给dpvs的length为184的包正确传输,但length为2的包一直在重传,且直至超时都没有成功,同时在client上的抓包显示,client收到了这个length为2的包,但是由于tcp checksum error被丢掉了,并没有交给上层应用去处理,这样就解释了为什么异常时的表现是hang住,因为某个数据包一直在重传,直至timeout。
通过上面的分析,我们又产生了疑问:现在的硬件网卡一般都具有csum offload的功能,能够通过网卡硬件帮我们做checksum,难道是网卡的checksum offload功能出现了问题?如果真是网卡硬件的offload功能出现问题,那影响的应该不是某一个特定的数据包,而是所有经过这块网卡的数据包才对,因此我们怀疑是网卡在针对某个特定数据包的计算checksum的时候产生了错误,为了验证这个问题,我们在dpvs上进行抓包分析,以下是抓包截图:
这个就是被不断重传的包,能够看到dpvs确实收到了这个包,并且处理逻辑也完全正常,剩下的步骤只有通过网卡做checksum并把这个数据包转发出去,问题似乎确实是出在了计算checksum这里,我们在分析这个包有什么特点,可以看到,这个包的初始大小=ethernet header length + ip header length + tcp header length + tcp data = 14 + 20 + 20 + 5 = 59,而我们知道,在网络中传输的数据帧最小长度为64字节,除去FCS的4字节(这部分也由网卡自行计算后添加在数据包末尾),最小长度应为60字节,也就是说,到达网卡的数据包如果不够60字节,那么网卡会在动在数据包末尾增加全0的padding来使数据包能够达到60字节,所以这个数据包也是需要网卡硬件来补充1字节的padding来达到最小传输长度。对此rfc894是这样规定的:
因此rs的网卡在数据包长度不足60字节时需要做两件事情:
- 补充1字节的padding达到最小长度60字节
- 补充的padding为全0
可以看到,在二层头中,确实有个补充的1字节的padding:ec,这个padding并没有按rfc894的规定填充成全0,而是填了非0值,这样就造成了dpvs的网卡在计算tcp checksum时把这个padding误当成了tcp data而计算了check sum,因此在client接收到这个数据包并根据ip伪头部和tcp头部计算出来的checksum与数据包tcp头部的checksum不一致,因此并没有把这个数据包交给上层应用处理而是直接drop。
----- 网卡手册针对 TCP/UDP checksum部分的说明
至此,问题的原因已经很明显了:部分机器的网卡在做padding时未按照rfc894的规定补充全0而是补充了其他值,导致dpvs的网卡在做checksum offload时padding的数据也参与了checksum的计算。
分析正常的rs和不正常的rs在网卡硬件上的差别,发现:网卡的硬件型号相同,驱动型号也相同,但不正常的网卡fireware与正常的网卡不相同,而fireware我们没有办法自行升级或降级。
整个故障的过程可以大概表示为:
client dpvs rs
---1--- >
< ---2---
< ---3---
步骤1:数据包正常,请求数据
步骤2:部分数据包初始长度小于60字节,需要网卡补充padding,网卡先计算checksum填入tcp包头后补充padding至数据包末尾,此时checksum正常,但padding不为全0
步骤3:dpvs收到步骤2的包进行正常转发逻辑处理后转发至网卡,由网卡计算checksum并转发,但在计算新的checksum时由于padding非全0导致checksum计算错误,client收到后丢弃了这个包
ps:以上是rs的网卡在添加padding时补充的不是全0,另一种场景是client的网卡在添加padding时补充的不是全0,这两种情况都会导致上述问题的出现。
问题解决
至此,我们已经能够解释最开始提出的三个问题:
dpvs已经在多个机房上线,运行时间已超过半年,为何突然有业务反馈异常
a:该业务是在某个核心机房上线了dpvs后出现了问题,其他机房很早上线了dpvs但由于其他机房是改业务的备份机房实际并未启用,因此半年多来一直没有发现问题
反馈问题的业务多与金融区相关(金融区由于其特殊性,会额外增加安全方面的加固策略)
a:排查发现是金融区的某一批次机器的fireware存在bug导致,与金融区本身的安全策略无关
为什么问题表现均为服务hang住
a:问题的实质是出现丢包,服务在等待响应,因此表现为hang住
接下来我们将解决该问题:
只要让dpvs在处理数据包时,忽略数据包以前的padding部分,而由dpvs的网卡重新去处理padding(由于网卡计算checksum是在补充padding之前,因此可以保证此时的checksum一定是正确的)。由于dpvs是基于dpdk开发的,数据包在dpvs中是以mbuf的结构保存和处理的,以下是mbuf的结构:
数据帧被存储在headroom和tailroom之间(与skb类似),pkt_len=data_len=整个数据帧的长度,我们要做的就是将padding从data中去除(放到tailroom中去),因此可以在数据包入口处添加以下代码:
int padding_length = mbuf->data_len - (mbuf->l2_len +rte_be_to_cpu_16(ipv4_hdr->total_length)); mbuf->data_len = mbuf->data_len - padding_length; mbuf->pkt_len = mbuf->data_len;
添加以上代码后测试通过,本次故障解决。
参考资料
https://tools.ietf.org/html/rfc894
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Docker 容器故障排查工具
- Kubernetes 网络故障常见排查方法
- Elasticsearch 集群故障排查及修复指南
- Golang RabbitMQ 故障排查一例
- Java 线上故障排查全套路
- [译] Kubernetes Deployment 故障排查常见方法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Transcending CSS
Andy Clarke、Molly E. Holzschlag / New Riders / November 15, 2006 / $49.99
As the Web evolves to incorporate new standards and the latest browsers offer new possibilities for creative design, the art of creating Web sites is also changing. Few Web designers are experienced p......一起来看看 《Transcending CSS》 这本书的介绍吧!