【linux性能】【详细】CPU性能分析---第1篇

一、CPU指标

CPU又称为中央处理器,是一块超大规模的集成电路,是一台计算机的运算核(Core)和控制核心( Control Unit)。它的功能主要是解释计算机指令以及处理计算机软件中的数据。

在这里插入图片描述

1 、cpu使用率
1.1 用户cpu使用率:
包括用户态cpu使用率(user)和低优先级用户态cpu使用率(nice),表示cpu在用户态运行的时间百分比。用户cpu使用率高,通常说明应用程序笔记繁忙。

1.2 系统cpu使用率:
表示cpu在内核态运行的时间百分比(不包括中断),系统cpu使用率高说明内核比较繁忙。

1.3 等待I/O的cpu使用率:
通常也称为iowait,表示等待I/O的时间百分比。iowait高,通常说明系统与硬件设备的I/O交互时间比较长。

1.4 软中断和硬中断的cpu使用率:
分别表示内核调用软中断、硬中断处理程序的四件百分比,他们的使用率高,通常说明系统发生了大量的中断。

1.5 虚拟化环境中用到的窃取cpu使用率(steal)和客户cpu使用率(guest),分别表示被其他虚拟机占用的cpu时间百分比,和运行客户虚拟机的cpu时间百分比。

2 、平均负载
也就是系统平均活跃进程数。理想情况,平均负载等于逻辑cpu个数,这表示每个cpu都恰好被充分使用。如果平均负载大于逻辑cpu的个数,就表示负载比较重了。

3 、上下文切换
本身是保证linux正常运行的一项核心功能。但过多的上下文切换,会将原本运行的cpu时间,消耗在寄存器、内核栈以及虚拟内存数据保存和恢复上,缩短进程真正运行的时间,成为性能瓶颈。

4 、cpu缓存命中率
cpu的发展速度远远高于内存的发展速度,cpu的处理速度就比内存的访问速度快得多。这样,cpu在访问内存的时候,免不了要等待内存的相应。为了协调这两者的巨大性能差距,cpu缓存(通常是多级缓存)就出现了:
在这里插入图片描述
cpu缓存的速度介于cpu和内存之间,缓存是热点的内存数据。根据不断增长的热点数据,这些缓存按照大小不同分为L1、L2、L3等三级缓存,其中L1和L2常用在单核中,L3则用在多核中。从L1到L3,三级缓存的大小依次增大,相应的性能一次降低(比内存还是好很多)。而他们的命中率,衡量的是cpu缓存的复用情况,命中率越高,则表示性能越好。

二、CPU性能分析

1、分析思路和步骤
(1)使用top分析CPU使用率,如果user%+sys%使用率过高,查看CPU使用过高的进程;
(2)使用top分析CPU平均负载,如果load average平均负载过高,可以辅助通过sar查看运行队列和平均负载,如果运行队列大于CPU个数且平均负载过高,查看CPU使用过高的进程;
(3)若CPU使用率过高或者CPU平均负载过高,通过vmstat确认系统的当前的上下文切换(cs)、中断次数(in);
(4)若上下文切换次数过大,通过 pidstat 查看是哪个进程或线程的切换次数过高并明确上下文切换过大的类型;
(5)若中断次数过大,通过top分析中断的类型,再通过 /proc/interrupts或/proc/softirqs分析是哪种中断类型;
(6)扩充:通过top监测僵尸进程,查看S列对应的进程名称和对应的进程号PID,再追踪该僵尸进程定位问题原因;
(7)问题深层次分析:
A、进程监控:通过strace来定位CPU进程的所有系统调用,更多的时候用在进程或服务异常时(比如:僵尸进程,进程忽然停止运行);
B、线程监控:通过show-busy-java-threads用于快速排查Java的CPU性能问题(top us值过高),自动查出运行的Java进程中消耗CPU多的线程,并打印出其线程栈,从而确定导致性能问题的方法调用;
在这里插入图片描述

2、命令工具使用
在这里插入图片描述
在这里插入图片描述

3、操作举例
(1)top分析CPU使用率:

命令:top
在这里插入图片描述

(2)top分析CPU平均负载:

命令:top
在这里插入图片描述
命令:sar -q

(3)若CPU使用率过高或者CPU平均负载过高,通过vmstat进一步分析

命令:vmstat 1
在这里插入图片描述
结果分析:
cs 列:上下文切换次数从之前 200 骤然上升到了 160w+…
in 列:中断次数已经达到 8w 了…说明中断处理也是个潜在的问题
r 列:就绪队列的长度最大到 8了,大于我们的 CPU 个数 4,所以会存在大量的 CPU 竞争
us、sy 列:两列的 CPU 使用率加起来上升到了 80-90,其中系统 CPU 使用率都是 60%+,说明 CPU 主要是被内核占用了(可以放在第一个)

(4)若上下文切换次数过大,通过 pidstat进一步分析

命令:pidstat -p 【pid】 -wt 1 10
在这里插入图片描述
结果分析:
Cswch/s:每秒主动任务上下文切换数量;
Nvcswch/s:每秒被动任务上下文切换数量,截图中看出nvcswch/s值很大,说明:进程被强制调度既争抢 CPU,CPU时间片不足。

(5)若中断次数过大,先通过top分析中断类型,再通过 /proc/interrupts或/proc/softirqs进一步分析

命令:top —分析中断类型
在这里插入图片描述
结果分析
CPU使用率不高,说明不是CPU问题,软中断程序 ksoftirqd占了0.6%的CPU,这已经相当大,属于异常。如下是进一步分析。

【5.1】软中断

命令:watch -d cat /proc/softirqs
在这里插入图片描述
结果分析:
通过 /proc/softirqs 文件内容的变化情况,你可以发现, TIMER(定时中断)、NET_RX(网络接收)、SCHED(内核调度)、RCU(RCU 锁)等这几个软中断都在不停变化,其中,NET_RX,也就是网络数据包接收软中断的变化速率最快。而其他几种类型的软中断,是保证 Linux 调度、时钟和临界区保护这些正常工作所必需的,所以它们有一定的变化倒是正常的。

扩充详细分析网络接收:
A、查看具体的网络状况是怎样,找出问题。使用 sar

命令:sar -n DEV 1
在这里插入图片描述
每秒接收12607帧,但只收到664kb字节,每帧只有50多字节 这显然是很小的网络帧,也就是通常所说的小包问题。

B、查看哪个端口发来的数据包。 使用 tcpdump

命令:tcpdump -i eth0 -n tcp port 80

# -i eth0 只抓取 eth0 网卡,-n 不解析协议名和主机名    
# tcp port 80 表示只抓取 tcp 协议并且端口号为 80 的网络帧    
# 因为只对外开放80端口,所以直接查看80.    

在这里插入图片描述
Flags [S] 则表示这是一个 SYN 包,从tcpdump会发现大量这样的包,所以确定就是这个IP在 SYN FLOOD 攻击。

解决方法:
SYN FLOOD 问题最简单的解决方法,就是从交换机或者硬件防火墙中封掉来源 IP,这样 SYN FLOOD 网络帧就不会发送到服务器中。

【5.2】硬中断

命令:watch -d cat /proc/interrupts
在这里插入图片描述
结果分析:
观察一段时间,可以发现变化速度最快的是重调度中断(RES),表示唤醒空闲状态的 CPU 来调度新的任务运行,这是多处理器系统(SMP)中,调度器用来分散任务到不同 CPU 的机制,通常也被称为处理器间中断(Inter-Processor Interrupts, IPI)
总结:硬中断次数升高是因为多任务的调度问题。

(6)通过top监测僵尸进程

命令:strace -o strace.log -tt -p 【pid】
在这里插入图片描述
现象:僵尸进程多;
说明:这可能是由于程序代码问题导致程序运行结束后,父进程没有对子进程进行回收,父进程结束后,子进程变成了僵尸进程,子进程还占用着大量的CPU资源,导致负载过高。
分析:通过这个进程日志,可以很明显的看出,读取 dubbo 配置文件是时候因为权限不够所以反复读取,出现一个死循环,造成僵尸进程。
解决:通过这个进程找到了配置文件的路径。然后给这个 lock 文件赋权,完美的解决问题。

(7)问题深层次分析:
A、进程监控—上面已演示,就不做演示了;
B、线程监控:通过show-busy-java-threads进一步分析Java进程中消耗CPU多的线程;
【7.1】下载show-busy-java-threads.sh脚本
【7.2】执行命令 sh show-busy-java-threads.sh

命令:sh show-busy-java-threads.sh
命令:bash show-busy-java-threads.sh
在这里插入图片描述分析:虽然找到了问题的根源,但是想要进一步解决它的话,需要更深层次的分析一下这个 dubbo 文件,于是我们就要取找到这个 dubbo 文件;
解决:参考以上第6项。

三、CPU优化

1、优化思路
(1)确认优化指标;
(2)获取优化指标数据;
(3)进行模拟测试时,需要注意测试工具不能和实验机在一个主机上。保证优化前后实验主机为同一个;
(4)通过数据确认优化可以带来较大提升的指标进行优化;
(5)对于这些指标进行优化,注意优化这些指标的双面性,带来的损失会不会比优化带来的效益更大。配合资源情况,做出合适的调整;
(6)测试优化结果;

2、优化操作
优化总结起来分为两个方向:一个是应用程序优化,一个是系统资源优化;

应用程序优化:
从应用程序的角度来说,降低CPU使用率的最好方法当然是,排除所有不必要的工作,只保留最核心的逻辑。比如减少循环的层次、减少递归、减少动态内存分配等等。
(1)编译器优化:很多编译器都会提供优化选项,适当开启它们,在编译阶段你就可以获得编译器的帮助,来提升性能。比如, gcc 就提供了优化选项 -O2,开启后会自动对应用程序的代码进行优化。
(2)算法优化:使用复杂度更低的算法,可以显著加快处理速度。比如,在数据比较大的情况下,可以用 O(nlogn) 的排序算法(如快排、归并排序等),代替 O(n^2) 的排序算法(如冒泡、插入排序等)。
(3)异步处理:使用异步处理,可以避免程序因为等待某个资源而一直阻塞,从而提升程序的并发处理能力。比如,把轮询替换为事件通知,就可以避免轮询耗费 CPU 的问题。
(4)多线程代替多进程:前面讲过,相对于进程的上下文切换,线程的上下文切换并不切换进程地址空间,因此可以降低上下文切换的成本。
(5)善用缓存:经常访问的数据或者计算过程中的步骤,可以放到内存中缓存起来,这样在下次用时就能直接从内存中获取,加快程序的处理速度。

系统优化:
优化 CPU 的运行,一方面要充分利用 CPU 缓存的本地性,加速缓存访问;另一方面,就是要控制进程的 CPU 使用情况,减少进程间的相互影响;
(1)CPU 绑定:把进程绑定到一个或者多个 CPU 上,可以提高 CPU 缓存的命中率,减少跨CPU 调度带来的上下文切换问题。
(2)CPU 独占:跟 CPU 绑定类似,进一步将 CPU 分组,并通过 CPU 亲和性机制为其分配进程。这样,这些 CPU 就由指定的进程独占,换句话说,不允许其他进程再来使用这些CPU。
(3)优先级调整:使用 nice 调整进程的优先级,正值调低优先级,负值调高优先级。优先级的数值含义前面我们提到过,忘了的话及时复习一下。在这里,适当降低非核心应用的优先级,增高核心应用的优先级,可以确保核心应用得到优先处理。
(4)为进程设置资源限制:使用 Linux cgroups 来设置进程的 CPU 使用上限,可以防止由于某个应用自身的问题,而耗尽系统资源。
(5)NUMA(Non-Uniform Memory Access)优化:支持 NUMA 的处理器会被划分为多个 node,每个 node 都有自己的本地内存空间。NUMA 优化,其实就是让 CPU 尽可能只访问本地内存。
(6)中断负载均衡:无论是软中断还是硬中断,它们的中断处理程序都可能会耗费大量的CPU。开启 irqbalance 服务或者配置 smp_affinity,就可以把中断处理过程自动负载均衡到多个 CPU 上。

说明
QQ群:775460627,欢迎对于测试志同道合的人加入,大家一起沟通交流!

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玻璃杯1992

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值