性能分析(5)- 软中断导致 CPU 使用率过高的案例
性能分析小案例系列,可以通过下面链接查看哦
https://www.cnblogs.com/poloyy/category/1814570.html
前言
软中断基本原理,可参考这篇博客:https://www.cnblogs.com/poloyy/p/13435519.html
中断
- 一种异步的事件处理机制,用来提供系统的并发处理能力
- 当中断事件发生,会触发执行中断处理程序
- 中断处理程序分为上半部和下半部
- 上半部:硬中断,快速处理中断
- 下半部:软中断,用来异步处理上半部未完成的工作
软中断
- 每个 CPU 都对应一个软中断内核线程,名字是 ksoftirqd/CPU 编号
- 当软中断事件的频率过高时,内核线程也会因为 CPU 使用率过高而导致软中断处理不及时,进而引发网络收发延迟,调度缓慢等性能问题
软中断频率过高案例
系统配置
Ubuntu 18.04, 2 CPU,2GB 内存,共两台虚拟机
三个工具
- sar:是一个系统活动报告工具,既可以实时查看系统的当前活动,又可以配置保存和报告 历史统计数据。
- hping3:是一个可以构造 TCP/IP 协议数据包的工具,可以对系统进行安全审计、防火墙 测试等。
- tcpdump:是一个常用的网络抓包工具,常用来分析各种网络问题
虚拟机关系
通过 docker 运行案例
在 VM1 中执行命令
docker run -itd --name=nginx -p : nginx
通过 curl 确认 Nginx 正常启动
在 VM2 中执行命令
curl http://172.20.72.58/
通过 hping3 模拟 Nginx 的客户端请求
在 VM2 中执行命令
hping3 -S -p -i u100 172.20.72.58
- -S:参数表示设置 TCP 协议的 SYN(同步序列号)
- -p:表示目的端口为 80
- -i:u100 表示每隔 100 微秒发送一个网络帧
回到 VM1
感觉系统响应明显变慢了,即便只 是在终端中敲几个回车,都得很久才能得到响应
分析系统为什么会响应变慢
以下命令均在 VM1 中执行
通过 top 命令查看系统资源使用情况
- 系统 CPU 使用率(用户态 us 和内核态 sy )并不高
- 平均负载适中,只有 2 个 R 状态的进程,无僵尸进程
- 但是软中断进程1号(ksoftirqd/1)的 CPU 使用率偏高,而且处理软中断的 CPU 占比已达到 94
- 此外,并无其他异常进程
- 可以猜测,软中断就是罪魁祸首
确认是什么类型的软中断
观察 /proc/softirqs 文件的内容,就能知道各种软中断类型的次数
这里的各类软中断次数,又是什么时间段里的次数呢?
- 它是系统运行以来的累积中断次数
- 所以直接查看文件内容,得到的只是累积中断次数,对这里的问题并没有直接参考意义
- 中断次数的变化速率才是我们需要关注的
通过 watch 动态查看命令输出结果
因为我的机器是两核,如果直接读取 /proc/softirqs 会打印 128 核的信息,但对于我来说,只要看前面两核的信息足以,所以需要写提取关键数据
watch -d "/bin/cat /proc/softirqs | /usr/bin/awk 'NR == 1{printf \"%-15s %-15s %-15s\n\",\" \",\$1,\$2}; NR > 1{printf \"%-15s %-15s %-15s\n\",\$1,\$2,\$3}'"
结果分析
- TIMER(定时中断)、 NET_RX(网络接收)、SCHED(内核调度)、RCU(RCU 锁)等这几个软中断都在不停变化
- 而 NET_RX,就是网络数据包接收软中断的变化速率最快
- 其他几种类型的软中断,是保证 Linux 调度、时钟、临界区保护这些正常工作所必需的,所以有变化时正常的
通过 sar 查看系统的网络收发情况
上面确认了从网络接收的软中断入手,所以第一步应该要看下系统的网络接收情况
sar 的好处
- 不仅可以观察网络收发的吞吐量(BPS,每秒收发的字节数)
- 还可以观察网络收发的 PPS(每秒收发的网络帧数)
执行 sar 命令
sar -n DEV
- 第二列: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
- -i ens33:只抓取 ens33 网卡
- -n:不解析协议名和主机名
- tcp port 80:表示只抓取 tcp 协议并且端口号为 80 的网络帧
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 的原理和更多解决思路在后面会讲到哦
分析的整体思路
- 系统出现卡顿,执行命令,响应也会变慢
- 通过 top 查看系统资源情况
- 发现 CPU 使用率(us 和 sy)均不高,平均负载适中,没有超 CPU 核数的运行状态的进程,也没有僵尸进程
- 但是发现处理软中断的 CPU 占比(si)较高,在进程列表也可以看到软中断进程 CPU 使用率偏高,猜测是软中断导致系统变卡顿的主要原因
- 通过 /proc/sorfirqs 查看软中断类型和变化频率,发现直接 cat 的话会打印 128 个核的信息,但只想要两个核的信息
- 所以结合 awk 进行过滤,再通过 watch 命令可以动态输出查看结果
- 发现有多个软中断类型在变化,重点是 NET_RX 变化频率超高,而且幅度也很大,它是网络数据包接收软中断,暂且认为它是问题根源
- 既然跟网络有关系,可以先通过 sar 命令查看系统网络接收和发送的整体情况
- 然后可以看到接收的 PPS 会比接收的 BPS 大很多,做下运算,发现网络帧会非常小,也就是常说的小包问题
- 接下来,通过 tcpdump 抓取 80端口的 tcp 协议网络包,会发现大量来自 VM2 发送的 SYN 包,结合 sar 命令,确认是 SYN FLOOD 攻击
性能分析(5)- 软中断导致 CPU 使用率过高的案例的更多相关文章
- 空循环导致CPU使用率很高
业务背景 业务背景就是需要将多张业务表中的数据增量同步到一张大宽表中,后台系统基于这张大宽表开展业务,所以就开发了一个数据同步工具,由中间件采集binlog消息到kafka里,然后我去消费,实现增量同 ...
- 性能分析(4)- iowait 使用率过高案例
性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 前言 前面两个案例讲的都是上下文切换导致的 CPU ...
- Oracle查询语句导致CPU使用率过高问题处理
解决此问题的关键在于如何找到造成CPU使用率过高的SQL语句.步骤如下: 1.使用Process Explorer工具查看到Oracle进程,双击Oracle进程,在弹出的属性窗口的Threads选项 ...
- 代码死循环导致cpu使用率过高
1. top命令查看进程pid 27081 2. ps -mp pid -o THREAD,tid,time (tid:31128) 3.printf “%x\n” number #将tid转换 ...
- 性能分析(1)- Java 进程导致 CPU 使用率升高,问题怎么定位?
性能分析小案例系列,可以通过下面链接查看哦 ps:这些分析小案例不能保证百分比正确,是博主学习过程中的总结,仅做参考 前提 本机有一个很占用 CPU 的项目,放在了 Tomcat 下启动着 如何定位 ...
- 性能分析(3)- 短时进程导致用户 CPU 使用率过高案例
性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 系统架构背景 VM1:用作 Web 服务器,来模拟 ...
- 性能分析(2)- 应用程序 CPU 使用率过高案例
性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 系统架构背景 其中一台用作 Web 服务器,来模拟 ...
- epoll 性能分析(解决占用CPU 过高问题)
针对自己写的一个服务器网络引擎Engine 文章后面附上源码 使用epoll 刚刚开始时候发现占用CPU 特别高,但是网络引擎里面基本没干什么事,不应该有这么高的CPU,一直不解, 于是自己慢慢的分 ...
- 性能测试分析过程(二)cpu 使用率过高的分析方法
Linux 系统下 cpu 使用率过高的分析方法 1.通过 top 命令可以很明显查看出哪个进程耗cpu比较高 2. ps -mp 25147-o THREAD,tid,time\top -Hp pi ...
随机推荐
- Java中多线程的使用(超级超级详细)线程安全原理解析 4
Java中多线程的使用(超级超级详细)线程安全 4 什么是线程安全? 有多个线程在同时运行,这些线程可能会运行相同的代码,程序运行的每次结果和单线程运行的结果是一样的,而且其他变量的值也和预期的值一样 ...
- Python Hacking Tools - Web Scraper
Preparation: Python Libray in the following programming: 1. Requests Document: https://2.python-requ ...
- 关于ES6的let和const
变量 var存在的问题 可以重复声明 无法限制修改 没有块级作用域 (在全局范围内有效) 存在变量提升 const/let 不可以重复声明 let a = 1; let a = 2; var b = ...
- C++头文件居然可以这么打!!!! 长见识了!!!
返回主页 longdie 这人,生于天,立于地,为的就是顶天立地. 未来的答案早已被宇宙计算好了,人类自出现,答案就在那里,人类灭亡了,答案也在那里,,但是人活着,不就是为了看看未来发生了什么吗?如果 ...
- 路径总和(leetcode 113)
题目描述如下所示: 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径.(https://leetcode-cn.com/problems/path-sum-ii/) ...
- Spring Boot 集成 WebSocket 实现服务端推送消息到客户端
假设有这样一个场景:服务端的资源经常在更新,客户端需要尽量及时地了解到这些更新发生后展示给用户,如果是 HTTP 1.1,通常会开启 ajax 请求询问服务端是否有更新,通过定时器反复轮询服务端响应的 ...
- setTimeout、clearTimeout、setInterval
setTimeout(cb, ms) setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb).:setTimeout() 只执行一次指定函数. 返回一个代表定时器的 ...
- 解决SyntaxError: Non-UTF-8 code starting with '\xbb'问题
在第一行加入 # coding=utf-8 2020-06-13
- Python while 中简单的语句组
Python while 中简单的语句组: 只使用 while: # 简单的语句组 a = 4 b = 8 num = 0 while a < b: print("a 比 b 小&qu ...
- PHP bin2hex() 函数
实例 把 "Hello World!" 转换为十六进制值: <?php 高佣联盟 www.cgewang.com$str = bin2hex("Hello Worl ...