(案例5)软中断导致 CPU 使用率过高

摘要:
Hping3:它是一个可以构建TCP/IP协议包的工具,可以对系统进行安全审计、防火墙测试等。

前言

软中断基本原理,可参考这篇博客:https://www.cnblogs.com/uestc2007/p/14684499.html

中断

  • 一种异步的事件处理机制,用来提供系统的并发处理能力
  • 当中断事件发生,会触发执行中断处理程序
  • 中断处理程序分为上半部和下半部
  • 上半部:硬中断,快速处理中断
  • 下半部:软中断,用来异步处理上半部未完成的工作 

软中断

  • 每个 CPU 都对应一个软中断内核线程,名字是 ksoftirqd/CPU 编号
  • 当软中断事件的频率过高时,内核线程也会因为 CPU 使用率过高而导致软中断处理不及时,进而引发网络收发延迟,调度缓慢等性能问题                          

软中断频率过高案例

系统配置

Ubuntu 18.04, 2 CPU,2GB 内存,共两台虚拟机

三个工具

  • sar:是一个系统活动报告工具,既可以实时查看系统的当前活动,又可以配置保存和报告 历史统计数据。
  • hping3:是一个可以构造 TCP/IP 协议数据包的工具,可以对系统进行安全审计、防火墙 测试等。
  • tcpdump:是一个常用的网络抓包工具,常用来分析各种网络问题

虚拟机关系

(案例5)软中断导致 CPU 使用率过高第1张

通过 docker 运行案例

在 VM1 中执行命令

docker run -itd --name=nginx -p 80:80 nginx

通过 curl 确认 Nginx 正常启动

在 VM2 中执行命令

curl http://172.20.72.58/

通过 hping3 模拟 Nginx 的客户端请求

在 VM2 中执行命令

hping3 -S -p 80 -i u100 172.20.72.58
  • -S:参数表示设置 TCP 协议的 SYN(同步序列号)
  • -p:表示目的端口为 80
  • -i:u100 表示每隔 100 微秒发送一个网络帧

回到 VM1

感觉系统响应明显变慢了,即便只 是在终端中敲几个回车,都得很久才能得到响应

分析系统为什么会响应变慢

以下命令均在 VM1 中执行

通过 top 命令查看系统资源使用情况

(案例5)软中断导致 CPU 使用率过高第2张

  1. 系统 CPU 使用率(用户态 us 和内核态 sy )并不高 
  2. 平均负载适中,只有 2 个 R 状态的进程,无僵尸进程
  3. 但是软中断进程1号(ksoftirqd/1)的 CPU 使用率偏高,而且处理软中断的 CPU 占比已达到 94
  4. 此外,并无其他异常进程
  5. 可以猜测,软中断就是罪魁祸首

确认是什么类型的软中断

观察 /proc/softirqs 文件的内容,就能知道各种软中断类型的次数

这里的各类软中断次数,又是什么时间段里的次数呢?

  • 它是系统运行以来的累积中断次数
  • 所以直接查看文件内容,得到的只是累积中断次数,对这里的问题并没有直接参考意义
  • 中断次数的变化速率才是我们需要关注的

通过 watch 动态查看命令输出结果

因为我的机器是两核,如果直接读取 /proc/softirqs 会打印 128 核的信息,但对于我来说,只要看前面两核的信息足以,所以需要写提取关键数据

 
watch -d "/bin/cat /proc/softirqs | /usr/bin/awk 'NR == 1{printf "%-15s %-15s %-15s
"," ",$1,$2}; NR > 1{printf "%-15s %-15s %-15s
",$1,$2,$3}'"

(案例5)软中断导致 CPU 使用率过高第3张

结果分析

  • TIMER(定时中断)、 NET_RX(网络接收)、SCHED(内核调度)、RCU(RCU 锁)等这几个软中断都在不停变化
  • 而 NET_RX,就是网络数据包接收软中断变化速率最快
  • 其他几种类型的软中断,是保证 Linux 调度、时钟、临界区保护这些正常工作所必需的,所以有变化时正常的

通过 sar 查看系统的网络收发情况

上面确认了从网络接收的软中断入手,所以第一步应该要看下系统的网络接收情况

sar 的好处

  • 不仅可以观察网络收发的吞吐量(BPS,每秒收发的字节数)
  • 还可以观察网络收发的 PPS(每秒收发的网络帧数)

执行 sar 命令

sar -n DEV 1

(案例5)软中断导致 CPU 使用率过高第4张

  • 第二列:IFACE 表示网卡
  • 第三、四列:rxpck/s 和 txpck/s 分别表示每秒接收、发送的网络帧数【PPS】
  • 第五、六列:rxkB/s 和 txkB/s 分别表示每秒接收、发送的千字节数【BPS】

结果分析

对网卡 ens33 来说

  • 每秒接收的网络帧数比较大,几乎达到 8w,而发送的网络帧数较小,只有接近 4w
  • 每秒接收的千字节数只有 4611 KB,发送的千字节数更小,只有2314 KB

docker0 和 veth04076e3

  • 数据跟 ens33 基本一致只是发送和接收相反,发送的数据较大而接收的数据较小
  • 这是 Linux 内部网桥转发导致的,暂且不用深究,只要知道这是系统把 ens33 收到的包转发给 Nginx 服务即可

异常点

  • 前面说到是网络数据包接收软中断的问题,那就重点看 ens33
  • 接收的 PPS 达到 8w,但接收的 BPS 只有 5k 不到,网络帧看起来是比较小的
  • 4611 * 1024 / 78694 = 64 字节,说明平均每个网络帧只有 60 字节,这显然是很小的网络帧,也就是常说的小包问题

灵魂拷问

如何知道这是一个什么样的网络帧,它又是从哪里发过来的呢?

通过 tcpdump 抓取网络包

已知条件

Nginx 监听在 80 端口, 它所提供的 HTTP 服务是基于 TCP 协议的

执行 tcpdump 命令

tcpdump -i ens33 -n tcp port 80
  • -i ens33:只抓取 ens33 网卡
  • -n:不解析协议名和主机名
  • tcp port 80:表示只抓取 tcp 协议并且端口号为 80 的网络帧

(案例5)软中断导致 CPU 使用率过高第5张

172.20.72.59.52195 > 172.20.72.58.80

  • 表示网络帧从 172.20.72.59 的 52195 端口发 送到 172.20.72.58 的 80 端口
  • 也就是从运行 hping3 机器的 52195 端口发送网络帧, 目的为 Nginx 所在机器的 80 端口

Flags [S]

表示这是一个 SYN 包

性能分析结果

结合 sar 命令发现的 PPS 接近 4w 的现象,可以认为这就是从 172.20.72.59 这个地址发送过来的 SYN FLOOD 攻击

解决 SYN FLOOD 问题

从交换机或者硬件防火墙中封掉来源 IP,这样 SYN FLOOD 网络帧就不会发送到服务器中

后续的期待

至于 SYN FLOOD 的原理和更多解决思路在后面会讲到哦

分析的整体思路

  1. 系统出现卡顿,执行命令,响应也会变慢
  2. 通过 top 查看系统资源情况
  3. 发现 CPU 使用率(us 和 sy)均不高,平均负载适中,没有超 CPU 核数的运行状态的进程,也没有僵尸进程
  4. 但是发现处理软中断的 CPU 占比(si)较高,在进程列表也可以看到软中断进程 CPU 使用率偏高,猜测是软中断导致系统变卡顿的主要原因
  5. 通过 /proc/sorfirqs 查看软中断类型和变化频率,发现直接 cat 的话会打印 128 个核的信息,但只想要两个核的信息
  6. 所以结合 awk 进行过滤,再通过 watch 命令可以动态输出查看结果
  7. 发现有多个软中断类型在变化,重点是 NET_RX 变化频率超高,而且幅度也很大,它是网络数据包接收软中断,暂且认为它是问题根源
  8. 既然跟网络有关系,可以先通过 sar 命令查看系统网络接收和发送的整体情况
  9. 然后可以看到接收的 PPS 会比接收的 BPS 大很多,做下运算,发现网络帧会非常小,也就是常说的小包问题
  10. 接下来,通过 tcpdump 抓取 80端口的 tcp 协议网络包,会发现大量来自  VM2 发送的 SYN 包,结合 sar 命令,确认是 SYN FLOOD 攻击

免责声明:文章转载自《(案例5)软中断导致 CPU 使用率过高》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇项目中使用Quartz集群分享--转载DCM 图片查看下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

关于跨平台的一些认识

前段时间看了 周志明的那本 《深入理解java虚拟机》。对于平台无关性问题,有了一些新的认识。所以特写一篇博客来进行总结。 这是我的第一篇不针对具体技术,而只针对计算机系统和原理的博客文章,而这种话题,总是比较宽泛,而我本人的水平有限,所以我也只能泛泛的写写,思考的不对的地方,还望读者不吝批评。 C为什么不能跨平台 咱们先来讨论一下,C语言的执行过程,从而...

GC日志时间分析

在GC日志里,一条完整的GC日志记录最后,会带有本次GC所花费的时间,如下面这一条新生代GC: [GC [DefNew: 3298K->149K(5504K), 0.0053498 secs] 3298K->3221K(9600K), .0053750 secs] [Times: user=0.00 sys=0.00, real=0.01 se...

什么是内存(二):虚拟内存

通过上一篇文章的扯淡,我们应该已经明白了存储器的层次结构,技术细节很复杂,但是思想却不难理解,因为就是很简单的缓存思想。那么本文我们开始讨论关于内存的另一个话题.虚拟内存。其实思想也是很容易理解的。 我不知道有多少人听过虚拟内存这个概念,但是虚拟内存是计算机系统最重要的概念之一,并且它成功的主要原因就是它一直在沉默的,自动的工作,换句话说,我们这些做应用的...

Linux中ps -ef , ps -aux命令的用法

Linux中ps -ef , ps -aux命令的用法 ## 其中各列的内容意思如下 UID //用户ID、但输出的是用户名 PID //进程的ID PPID //父进程ID C //进程占用CPU的百分比 STIME //进程启动到现在的时间 TTY //该进程在那个终端上运行,若与终端无关,则显示? 若为pts/0等,则表示由网络连接主机进程。 CM...

CPU上下文切换分析

一、CPU上下文切换 1、上下文切换,有时也称做进程切换或任务切换,是指CPU从一个进程或线程切换到另一个进程或线程。 2、vmstat是一个常用的系统性能分析工具,主要用来分析系统内存使用情况,也常用来分析CPU上下文切换和中断的次数。 例:vmstat -w 上下文切换需要特别关注的四列内容: cs(context switch)  是每秒上下文切换...

Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3

一、现代操作系统的权限分离:   现代操作系统一般都至少分为内核态和用户态。一般应用程序通常运行于用户态,而当应用程序调用系统调用时候会执行内核代码,此时会处于内核态。一般的,应用程序是不能随便进入内核态的而是需要向OS申请,因为内核态拥有更高的权限。所以当程序运行的时候,其实是有两个栈的,一个位于用户态,一个位于内核态。他们之间会按照操作系统的规定进行通...