系统调用导致网络收包卡顿的问题分析

前言

G行某平台类应用系统提供高并发、低延迟的服务请求,该系统的的响应时间在1毫秒左右,目前最大TPS在2.5万左右,为保证该系统的快速响应,系统设置的超时时间为30毫秒。在一次巡检中发现,该系统的几台服务器超时交易笔数在逐渐增加,为避免系统运行风险,协调网络、操作系统等专家一同分析,在分析过程中补充学习了大量Linux操作系统内核的知识,现将分析过程及其中用到的知识点记录下来,以便为解决类似的问题提供一个通用的解决思路。

一、应用系统超时现象

外部系统将请求发送到前端服务,前端服务进行业务逻辑后重新组装报文,将请求发送到后端服务。交易处理超时体现在前端服务对后台服务的请求上,但是根据网络设备的镜像网络包分析,后端服务的处置时间没有异常,前端发送给后端的请求,后端都可以快速的处理。因此问题还是出现在前端服务上。

系统调用导致网络收包卡顿的问题分析插图亿华云

图1 系统逻辑架构

由于该系统的交易量大、响应时间低,所以对处理过程的日志记录较少,根据前端服务的应用日志无法定位根本原因。针对前端服务到后台服务的请求,选一段超时交易较多的时间段的网络镜像包进行分析。发现超时交易集中在两个固定的时间点,分别为:11:29:4.200,超时9笔,平均TCPack_rtt为5毫秒;11:29:54.100,超时2笔,平均TCPack_rtt为6毫秒,在这两个时间段超时交易的rtt都大于30毫秒,没有超时的交易也有部分ack的rtt相对较长。其他正常交易时间段的ack_rtt在0.06毫秒左右。

系统调用导致网络收包卡顿的问题分析插图1亿华云

图2 网络镜像包异常现象

根据这个现象初步怀疑在网络收发包上出现了拥堵问题,操作系统网络协议栈对收到的网络包没有及时处理。具体处理过程为前端发送请求到后端服务,后端服务立即进行了响应并返回响应包,由于协议栈没有及时处理响应包,导致相应的ack包没有及时返回,同时导致前端服务没有及时收到后端服务的返回,从而出现超时的现象。

为验证怀疑的方向,将一台服务器进行物理重启,重启后超时现象消失;同时将另外一台服务器只重启应用系统,超时现象没有出现缓解。因此可以确定交易的超时现象是由于操作系统的原因导致,和应用系统的处理性能无关。

二、问题排查

由于怀疑和操作系统的协议栈处理有关,为便于问题排查,同时避免对生产的稳定运行造成影响,我们使用perf和hping3进行异常的复现和问题分析。perf是Linux的一款性能分析工具,能够进行系统内核函数级和指令级的热点查找,可以用来分析程序中热点函数的CPU占用率,从而定位性能瓶颈。Hping3是一个开源网络工具,通过rawSocket直接组装icmp、udp、tcp报文,并记录对方服务器的ack响应时间。

系统调用导致网络收包卡顿的问题分析插图2亿华云

图3 问题排查方案

分析方案是找同子网的另外一台服务器部署hping3工具,向异常服务器不停的发送tcp报文,并记录ack返回出现延迟的时间点。在异常的服务器上部署perf工具,跟踪操作系统的内核调用,以便发现异常点。通过hping3每1毫秒发送一个网络包,记录其收到ack包的时间,可以发现在1650140557这个时间点出现大量rtt时间较长的情况,分析perf工具采集的内核调用数据,可以发现在相同的时间点存在大量ss进程发起的请求,当时正在执行的系统调用函数为read,根据调用栈proc_reg_read可以定位为程序正在读取/proc目录下的文件内容。

系统调用导致网络收包卡顿的问题分析插图3亿华云

系统调用导致网络收包卡顿的问题分析插图4亿华云

图4 内核系统异常调用栈

由于生产服务器上部署了各种代理和大量的监控脚本,因此怀疑是由这些代理、监控脚本发起的ss命令调用,在系统中查找使用ss命令的脚本,可以发现调用ss的命令行为图5所示。

系统调用导致网络收包卡顿的问题分析插图5亿华云

图5 触发异常的shell调用

通过strace跟踪ss 调用过程,如图6所示。

系统调用导致网络收包卡顿的问题分析插图6亿华云

图6 trace跟踪ss调用过程

关注read处理较慢的系统调用,可以发现read处理时间超过10ms的地方共有5处,最长的处理时间在189ms;根据文件句柄号3,可以确认正在读取的文件为”/proc/slabinfo”。

系统调用导致网络收包卡顿的问题分析插图7亿华云

图7 ss命令系统调用的异常

至此可以确认网络包接收卡顿,是由于监控周期性调用ss命令导致。ss命令会读取/proc/slabinfo,而在读取的时候有部分read函数的系统调用处理较慢,从而影响了网络接收包的处理。

为进一步验证上述结论,我们将异常服务器上使用ss命令的监控脚本停止,并启动前端服务将其加入生产队列,经过长时间观察,未再发现超时现象。然后手工在服务器上连续执行几次cat /proc/slabinfo,可以发现超时现象再次出现。

三、深入分析原因

1.第一个疑问:为什么读取/proc/slabinfo会导致网络包接收卡顿?

网络协议栈接收tcp报文并自动返回ack,是操作系统在中断中处理的,优先级别较高,而用户读取/proc/slabinfo是一般的系统调用,为什么会影响内核的中断处理呢?首先需要了解一下Linux操作系统代码执行的几个上下文场景。

硬件中断上下文:优先级别最高,只要有硬件中断发生就会被立即执行,这里包括时钟中断、网卡中断;

软件中断上下文:在硬件中断执行完成或系统调用完成时执行,这个是操作系统内核核心代码执行的主要环境,包括进程调度,网络协议栈处理等等;

内核进程上下文:运行在内核态,但是受进程调度管理,按进程调度分配的时间片执行,超过执行的时间片就有可能被别的进程抢占而暂停执行;

用户进程上下文:这个是大部分应用程序执行的环境,受进程调度管理,按进程调度分配的时间片执行,超过执行的时间片会强制进行进程切换。

那他们的执行优先级是不是就是:硬件中断

THE END
Copyright © 2024 亿华云