写点什么

抽丝剥茧:生产环境中负载均衡产品 DPDK 问题的解决(下)

  • 2019-11-11
  • 本文字数:2363 字

    阅读完需:约 8 分钟

抽丝剥茧:生产环境中负载均衡产品DPDK问题的解决(下)

三、流量镜像,确认异常包

第二步结论让整个排查前进了一大步,但是队列包是经过一系列程序处理的,并不是真正的原始业务报文。不达目的不罢休,关键时刻还是要上镜像抓包,于是当晚紧急联系网络运维同事在交换机上配置 port-mirroring(端口镜像),将发往 ULB4 集群的流量镜像到一个空闲服务器上进行镜像抓包。当然,镜像服务器还需要做特殊配置,如下:


设置网卡混杂模式,用于收取镜像流量(ifconfig net2 promisc)。


关闭 GRO 功能(ethtool -K net2 gro off),用于收取最原始的报文,防止 Linux 的 GRO 功能提前将报文进行组装。


根据异常 IP 的地域特性,我们针对性抓取了部分源 IP 段的流量。


参考命令:


nohup tcpdump -i net2 -s0 -w %Y%m%d_%H-%M-%S.pcap -G 1800 “proto gre and (((ip[54:4]&0x11223000)==0x11223000) or ((ip[58:4]&0x11223000)==0x11223000))” &


经过多次尝试后,功夫不负有心人,故障出现了,经过层层剥离筛选,找到了如下报文:



这是 IP 分片报文,但是奇怪的是 IP 分片的第二片只有 IP 头。经过仔细比对,这两个报文合在一起就是导出队列报文中的那两个连在一起的报文。后 26 字节和全 0 报文完全吻合。


我们知道在 TCP/IP 协议中,如果发送时一个 IP 报文长度超过了 MTU,将会触发 IP 分片,会被拆成多个小的分片报文进行发送。正常情况下,所有的分片肯定都是携带有数据的。但是这一个分片报文就很异常,报文的总长度是 20,也就是说只有一个 IP 头,后面不再携带任何信息,这样的报文是没有任何意义的。这个报文还因为长度太短在经过交换机后被填充了 26 字节的 0。


至此,我们最终找到了这个异常报文,也基本验证了我们的猜测。但是还需要去实际验证是否为这种异常报文导致。(从整个报文的交互来看,这一片报文本来是设置了不可分片的 TCP 报文,但是在经过某个公网网关后被强制设定了允许分片,并且分片出了这种异常的形式。)

四、解决方案

如果确实是这个异常报文导致的,那么只要在收包时对这种异常报文进行检查然后丢弃就可以了。于是,我们修改 DPDK 程序,丢弃这类报文。作为验证,先发布了一台线上服务器,经过 1 天运行再也没有出现异常容灾情况。既然问题根因已经找到,正是这种异常报文导致了 DPDK 工作异常,后续就可以按灰度全网发布了。

五、DPDK 社区反馈

本着对开源社区负责任的态度,我们准备将 BUG 向 DPDK 社区同步。对比最新的 commit 后,找到 11 月 6 日提交的一个 commit,情况如出一辙,如下:


ip_frag: check fragment length of incoming packet



DPDK 18.11 最新发布的版本中,已对此进行了修复,和我们处理逻辑一致,也是丢弃该异常报文。


复盘和总结

处理完所有问题后,我们开始做整体复盘。

一、ULB 无法发包的成因总结

ULB4 无法发包的整个产生过程如下:


DPDK 收到分片报文中的第一片,将其缓存下来等待后续分片;


第二片只有 IP 头的异常分片到来,DPDK 按照正常的报文处理逻辑进行处理,并没有进行检查丢弃,于是两片报文的 rte_mbuf 结构被链在一起,组成了一个链式报文返回给 ULB4;


这样的报文被 ULB4 接收后,因为整个报文的总长度并没有达到需要分片的长度,所以 ULB4 直接调用 DPDK 的发送接口发送出去;


DPDK 没有对这种异常报文进行检查,而是直接调用相应的用户态网卡驱动直接将报文发送出去;


用户态网卡驱动在发送这样的异常报文时触发了网卡 tx hang;


触发 tx hang 后,网卡不再工作,驱动队列中报文对应的发送描述符不再被网卡正确设置发送完成标记;


后续的报文持续到来,开始在发送队列中积压,最终将整个队列占满,再有报文到来时将被直接丢弃。

二、为什么异常报文会触发网卡 tx hang

首先我们看下 DPDK 中跟网卡发送报文相关的代码。




从以上的图中我们可以看到,根据网卡的 Datasheet 对相关字段进行正确设置非常重要,如果某种原因设置错误,将可能会导致不可预知的后果(具体还是要参考网卡的 Datasheet)。


如下图所示,通常网卡对应的 Datasheet 中会对相应字段进行相关描述,网卡驱动中一般都会有相应的数据结构与其对应。



在有了基本了解后,我们猜想如果直接在程序中手动构造这种类似的异常报文,是否也会导致网卡异常不发包?


答案是肯定的。


如下图所示,我们使用这样的代码片段构成异常报文,然后调用 DPDK 接口直接发送,很快网卡就会 tx hang。


三、对直接操作硬件的思考

直接操作硬件是一件需要非常谨慎的事情,在传统的 Linux 系统中,驱动程序一般处于内核态由内核去管理,而且驱动程序代码中可能进行了各种异常处理,因此很少会发生用户程序操作导致硬件不工作的情况。而 DPDK 因为其自身使用用户态驱动的特点,使得可以在用户态直接操作硬件,同时为了提升性能可能进行了非常多的优化,如果用户自身程序处理出问题就有可能会导致网卡 tx hang 这样的异常情况发生。

四、工具的价值

我们编写了一键导出 DPDK 驱动队列报文的工具,这样就可以在每次出现问题时,快速导出网卡驱动发送队列中的所有报文,大大提高了排查效率。这个工具再优化下后,准备在 UCloud GitHub 上开源,希望对 DPDK 开发者有所帮助。

写在最后

DPDK 作为开源套件,通常情况下稳定性和可靠性不存在什么问题,但是实际的应用场景千变万化,一些特殊情况可能导致 DPDK 工作异常。虽然发生概率很小,但是 DPDK 通常在关键的网关位置,一旦出现了问题,哪怕是很少见的问题也将会产生严重影响。


因此技术团队理解其工作原理并对其源码进行分析,同时能够结合具体现象一步步定位出 DPDK 存在的问题,对提高整个 DPDK 程序的服务可靠性具有重要意义。值得一提的是,ULB4 的高可用集群架构在本次问题的处理过程中发挥了重要作用,在一台不可用的时候,集群中其他机器也可以继续为用户提供可靠服务,有效提升了用户业务的可靠性。


本文转载自公众号 UCloud 技术(ID:ucloud_tech)。


原文链接:


https://mp.weixin.qq.com/s/JgX_hNsRtEK1poaJU9-LrQ


2019-11-11 14:591371

评论

发布
暂无评论
发现更多内容

分布式性能测试框架用例方案设想(二)

FunTester

分布式 性能测试 接口测试 测试框架 测试开发

鸿蒙内核之内存调测:动态内存池信息统计

华为云开发者联盟

鸿蒙 内存 动态内存池 内存信息

架构学习总结

c

架构实战营

深度学习中的分布式训练

安第斯智能云

人工智能 深度学习

【Vue2.x 源码学习】第二十四篇 - 异步更新流程

Brave

源码 vue2 8月日更

知道ThreadLocal吗?一起聊聊到底有啥用

华为云开发者联盟

Java 架构 线程 ThreadLocal 链路

科技融合:Hightopo受邀参加厦门公安科技活动周

一只数据鲸鱼

数据可视化 智慧公安 智能化 安全态势

高亮的架构毕业总结

高亮

架构训练营

【LeetCode】加一Java题解

Albert

算法 LeetCode 8月日更

LeetCode题解:173. 二叉搜索树迭代器,递归,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

面试官:你说说一条查询SQL的执行过程

艾小仙

高防服务器选择注意的三大方面

九河云安全

Lucene 倒排索引原理

Qunar技术沙龙

数据库 全文检索 lucene 倒排索引 搜索

应对极端天气,百度智能云推出城市内涝智能监测预警系统

科技热闻

1个月学会Java开发!2021年最新Java面试点梳理

策划Java工程师

Java 程序员 后端

一文带你搞定AOP切面

华为云开发者联盟

spring aop 切面编程 面向切面编程 切面

PostgreSQL 中如何控制行级安全和列级安全

Qunar技术沙龙

sql postgresql 运维 安全 权限

Springboot 配置文件、隐私数据脱敏的最佳实践(原理+源码)

程序员小富

Java springboot 数据安全 数据脱敏

AudioTracker实用封装

Changing Lin

8月日更

图分析在吴亦凡事件中的应用场景

6979阿强

图算法 图计算 GraphScope 吴亦凡 一站式图计算平台

2021Java春招面试真题:记一次蚂蚁金服Java研发岗的面试经历

策划Java工程师

Java 程序员 后端

Design for failure常见的12种设计思想

架构精进之路

降级 重试 容错 8月日更

kafka SpringBoot

Rubble

kafka springboot 8月日更

重磅 | 用友《数字化中台》震撼上市!数智化转型和商业创新实践的企业级经验!

博文视点Broadview

百度爱番番移动端网页秒开实践

百度Geek说

大前端 优化 网页加速 移动端

译文 | 四种产品经理成长框架,你是哪一种?

LigaAI

产品经理 产品管理 PM

复杂多变场景下的Groovy脚本引擎实战

vivo互联网技术

敏捷开发 脚本语言

手撸二叉树之对称二叉树

HelloWorld杰少

算法和数据结构 8月日更

原来select语句在MySQL中是这样执行的!看完又涨见识了!这回我要碾压面试官!

冰河

MySQL 面试 精通MySQL SELECT查询流程 查询缓存

基于docker的分布式性能测试框架功能验证(二)

FunTester

分布式 性能测试 接口测试 测试框架 测试开发

万字深入HarmonyOS ACE UI框架解析,带你看懂UI渲染流程

科技汇

抽丝剥茧:生产环境中负载均衡产品DPDK问题的解决(下)_服务革新_俞文俊_InfoQ精选文章