查看原文
其他

netinfo:揭开网络抖动面纱的神器

品文、牛衣、君然 云巅论剑 2022-05-30

一、引子

上回说狄仁杰接到搪报,官道出了桩大案,一行人火速赶往现场。此时曾泰身为刺史早已在案发现场反复勘查,却毫无头绪。
相关阅读《coredump 瘦身风云》
正一筹莫展之际,狄公一行赶到,曾泰忙上前讲述案情:前几日部分兵士哗变,我花几天时间回溯了案件,发现根因竟是在官道上丢失了十几石军盐所致。最近官道上小问题酿成大案之类的事情频出,作为一方刺史,倍感压力。
元芳探了下现场,连连摇头:这官道上人车络绎不绝,几天前丢失的东西,早已无踪可寻。狄公笑了笑:曾泰啊,青囊那正好有一样神器:netinfo 监控系统,或可解你燃眉之急。曾泰满心欢喜的望向青囊,只见青囊将此神器娓娓道来。

二、netinfo

青囊清清嗓子,netinfo 神器目的是监控业务是否发生了抖动,以及什么原因发生了网络抖动?何为网络抖动呢?网络作为操作系统系统关键组成部分,是业务稳定运行的重要基石之一。网络抖动是指在某一时刻业务的流量下跌、正常业务指标受损,网络出现延迟等,它在服务器集群里是一个高发和疑难问题,原因在于它的链路很漫长、协议相当复杂、涉及到的模块和节点较多,因此定位非常困难。我们将抖动分为当前发生的可一直复现的毛刺问题,以及过去某一时刻发生的业务抖动。
针对前一种,可以通过构造探测报文,自定义协议头(支持 icmp、tcp 和 udp),预留 timestamp 选项,沿途经过的节点识别出这个探测报文后,打上相应的时间戳,最后把所有的时间戳取出来,分析和定界问题。这种方法我们叫做 pingtrace。另外一种方式就是对真实的业务报文经过的函数利用 eBPF 技术动态打点来取得报文时间信息,这个功能我们称为 rtrace。目前这两个工具,都搜集在青囊的 sysAK 工具集里。
如果是第二种,由于问题不再复现,这个时候需要增加一些监控手段,把历史某个时间点的系统状态、端口计数等信息收集起来是不是就能判定抖动根因了?答案是否定的。如果单纯从网络本身的丢包和 tcp 的连接状态信息来判断,显然还不够。还需要看当时 io 是否 hang 住,内存是否 oom,系统是否宕机,中断是否有突发,调度是否延迟等。通过这些功能点,提取单个vm的健康度指标,最终把集群里的共性事件,通过离群统计算法来确定抖动根因。我们称这个监控系统叫 netinfo。 
如下图所示,netinfo 主要由数据采集和数据分析告警两部分功能组成:

2.1、数据采集

青囊顿了顿,开始把重心放在如何采集数据上来。就像这官道上,不搜集来往马队的脚印、车轮印,如何破案,巧妇难为无米之炊啊。netinfo 在收集传统操作系统基础指标(cpu\mem\io\net等)的基础上,结合网络抖动问题的特点,在以下方面进行增强:

2.1.1、netMonitor

netMonitor 主要用于网络异常事件检测,由以下子功能组件构成:
  • pktDrop:用于异常包行为监控,如重传、buffer 满、错包、路由不存在等情形;
  • socketState:socket状态监控,用于检查网络性能瓶颈等场景;
  • zeroProbe如下图所示,当 tcp 发生零窗口事件后,意味着接收缓冲区已满导致网络传输暂停;同时零窗口探测依赖于定时器实现,在丢失 ack 报文的场景下,网络性能将会急剧下降导致业务抖动;
  • rtoProbe:tcp 发生丢包后,在快速重传无法激活的场景下,需要依赖于 RTO重传定时器来触发重传,这个定时器间隔一般为 200ms,该场景对网络性能影响较大;需要及时监控识别出来。
同时,通过 eBPF 在 tcp 重传函数里进行 kprobe,获取 tcp_sock 结构体信息,将当前连接的发送和接收信息打印出来,如 snd_una、snd_nxt、rcv_nxt、rcv_wnd等,通过后端分析,可以确认连接的 buffer 使用情况、连接状态等。
另外,通过平滑曲线 SRTT(smoothed round trip time)图,可以观察延时的变化情况,判断连接的 srtt 是否抖动。如果业务发生了抖动,srtt 很稳定,很可能不是网络问题,可能是业务本身或调度、io 等的问题。反之,如果 srtt 发生了抖动,那么通过上面的连接信息,进一步确认是发送还是接收队列或是驱动问题。
  • resetProbe:TCP 复位报文场景探测,共有监听套接字不存在、握手阶段 ACK不合法、SYN 报文错误、RESET 报文错误、TCP 状态机异常等八类场景。

2.1.2、pingtrace

pingTrace 是一项主动网络时延探测工具,通过定时向对端发送延时探测报文,收集该报文在不同关键路径上的时间戳,进而计算网络通路上所有时延数据,来确定抖动问题边界。通过常态化监控主机到特定网元,可以实时获取历史发生的时延信息,确定抖动发生在用户、内核协议栈、驱动还是外部链路,以此来定界和定位问题发生点。
2.1.3、runlatency
runlatency 是一项任务调度延迟探测工具,通过比较任务唤醒和任务调度时间戳,用于检测出调度异常导致网络抖动的场景。

2.1.4、oomProbe

oom 往往会伴随业务进程重拉导致网络流量抖动,oomProbe 通过探测 oom 事件,并给出 oom 原因:如内存超出水位线、内存碎片化等。

2.1.5、iohang

当发生 io busy 持续长时间打满时,即启动 iohang 检测,用于判断 hang 源头时来自于前端(guestOS)还是后端。
iohang 是一项检测系统 io hang 的工具,其通过扫描 io 请求队列上的请求,根据每个未完成 io 的生产时间,到当下时间,是否已经超出业务所能容忍的时间长度来判断,如果存在这样的 io,我们将提取 io 的关键信息进行分析,定界问题所在,帮助快速定位。
2.1.6、iolatency
当发生 io await 时间过长时,即启动 iolatency 检测,用于判断 io 延迟消耗在哪。
iolatency 是一项 IO 延迟探测工具,通过探测真实 io 报文,收集一个 io 在一个生命周期内不同关键路径上的时间戳,进而计算 IO 路径上的所有时延数据,来确认 io 耗时最大的路径,以此确认是磁盘侧的耗时或者软件上的耗时。

2.2、数据分析与告警

一口气介绍了如此多的信息,青囊赶紧喝口水。数据拿回来了,得去分析啊。先把数据做个分类吧。netinfo 数据类型分为定时巡检(如系统基础指标、pktDrop、pingtrace 等数据)和实时上报(如 xProbe、runlatency 等数据)两类,每天每个实例会产生 100M 的数据需要处理,这些数据需要进行高效分析后以检测抖动根源。

2.2.1、流量下跌探测

网络抖动往往会伴随着原来平稳运行的流量出现明显下跌。常见的流量异常检测算法(如pyculiarity、pycaret等),对 CPU 运算要求更高,更适合单一流量异常检测的场景。而 netinfo 场景需要实时对每个实例的流量进行检测,对于计算效率要求更高。经过反复实践,对常规的协方差运算进行优化可以以较低的 cpu 占用即可以完成高效的流量下跌的检测。

2.2.2、离群指标挖掘

青囊说到兴奋处,旁边不时投来称赞声,青囊提高音量开始对引以为豪的功能,进行重点介绍了,这时全场人开始屏住呼吸,对这个核心功能翘首以盼。netinfo 会采集 60+ 项系统指标,哪些因素会对抖动带来直接影响?传统的经验判断的方法严重依赖于人工分析,工作量大不说,还容易出错。
如何在数十个指标中快速找到异常点?netinfo 在检测到抖动后,会先汇集所有指标进行组合,进行离群检测。以下图为例,对 cpu 和内存组合进行离群分析,找到离群点,如果该离群点可以和抖动信息对应得上,那该因素导致的问题可能性就非常高了。此时就可以从该离群点的根因入手,来判断是否与抖动有关联了。
曾泰此时握住青囊的手说,何处可寻此神器?青囊随手一摆,献上sysAK 链接:
https://codeup.openanolis.cn/codeup/sysAK/sysak.git
曾泰大呼妙哉妙哉,恍然大悟,原来 sysAK 中文名就是青囊啊,sysAK 本是龙蜥社区(OpenAnolis)开源社区的一个项目,不禁啧啧称赞,里面还有这么多宝贝工具。

三、三个月后

曾泰坐镇洛阳府衙大堂,足不出户,各路官道和商道数据均汇聚于此,每出险情均可通过 netinfo 系统知晓根因并及时签派公人到场解决;数月以来的疲敝一扫而空,不禁心中大快,对在一旁协助的青囊不住地称赞。
忽然,一书吏呈上一封急递,曾泰拆阅后,不舍地对青囊说:这些日子多亏了你,本来想多留你一些时日。但近日邗沟连发沉船大案,阁老要你一同前去。
欲知后事如何,且听下回分解。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存