列举了一些常见CPU性能问题,如下:
1.性能工具版本低,指标不全
pidstat的 %wait指标,说明进程等待CPU的百分比,是systat 11.5.5版本才引入的新指标,旧版本没有
那么,在没有的时候,我们可以使用proc文件系统来进行完成,我们可以更加直观的理解系统的工作原理
2.使用stress命令,无法模拟iowait升高的场景
stress -i 1 –timeout 600 模拟sync,平均负载升高,但是mpstat -P ALL 5 1 中iowait并没有升高太多
stress 无法模拟iowait升高,但是有sys升高,设计到了stress -i的原理,因为是模拟系统调用 sync()来测试 IO问题
但是sync()是刷新内存缓冲区的数据到磁盘,确保压力,如果缓冲区中没有多少数据,那么读写到磁盘中的数据就不多,也没法产生IO压力
所以可以使用 stress -ng来代替stress
stress -ng -i 1 -hdd 1 -timeout 600
3.无法出现RES中断的问题
运行了大量的线程,无法模拟出重调度中断RES升高的问题,在CPU上下文切换的案例中说过,重调度中断是调度器分散任务到不同CPU的机制,唤醒空闲状态的CPU,调度新任务运行,需要借助处理器间中断来实现
故此,在单核上没有什么意义了,因为不会发生重调度的情况
但是上下文切换的问题仍然存在
因为过多的线程在争抢一个CPU
4.无法模拟IO瓶颈和IO压力多大的问题
这个可能是每个人的机器配置不一致导致,每个人的机器配置中,既包括了CPU和内存配置的不同,也是磁盘的不同,HDD和SSD的性能具有一定的性能差异
5.性能工具 诸如vmstat的第一行数据差异较大
这个应该是命令本身的问题,第一行的数据是系统启动以来的平均值,其他才是运行vmstat的时候,设置的间隔时间的平均值
6.perf工具中,看到的并不是函数名,而是16进制地址
使用perf top -g -p 并不能看到php-fpm的调用关系
源于下面的错误信息
Failed to open /opt/bitnami/php/lib/php/extensions/opcache.so, continuing without symbols |
perf找不到分析进程依赖的库,这是Docker容器应用依赖的库都在namespace中导致的
对于此问题,可以如下解决
(1),容器外部再次构建相同路径的库,但是比较麻烦,而且,构建这些路径,往往会污染主机环境
(2),容器内部运行perf,这要求容器运行在特权模式下,实际的应用程序只以普通容器的方式运行,所以容器内部一般没有权限执行perf分析
(3),指定符号路径为容器文件系统的路径,需要使用bindfs来绑定目录
(4),容器外部保存分析目录,容器内查看,perf record -g -p <pid>
将perf.data cp到容器内运行分析
在容器内,安装perf 使用perf report解析报告
apt-get update && apt-get install -y linux-tools linux-perf procps
perf_4.9 report
别忘了,因为容器内外的环境不一样,我们需要注意安装的工具版本是否一致
之后我们就可以看到对应的sqrt调用栈了
7.如何使用perf工具分析Java程序
java这种利用JVM运行的应用程序,运行堆栈都是JVM内置的函数和堆栈管理,所以,从系统层面只能看到JVM的函数栈,不能直接得到Java应用程序的堆栈,perf_events已经支持了JIT,需要一个
/tmp/perf-PID.map的文件,进行符号翻译,开源项目 perf-map-agent可以生成这个符号表
为了生成全部调用栈,需要开启JDK的选项 -XX: +PreserveFramePointer,这样就可以查看了
8.perf报告中,很多符号不显示调用栈
perf record -g显示只有部分函数有 + ,其他都无法展开
perf report是一个可视化展示perf.data的工具,常见的输出如下
上面只有swapper是可以展开调用栈的,其他都不可以
这种情况需要通过man命令来查看 -g选项等于 –call-graph,
默认要求最小阈值threshold为0.5%才会打印,事件比例超过0.5%才会显示调用栈,那么我们应用app的事件比例,只有0.34%,低于0.5%,所以看不到app的调用栈
所以我们设置perf report为小于0.34的阈值,看到对应的调用栈
perf report -g graph,0.3
9.perf中的swapper是什么?
perf中的swapper高达99%的比例,理论上应该直接观察这个,但是swapper是系统初始化的时候创建的init进程,之后,就成为了一个最低优先级的空闲任务,当CPU上没有其他的任务运行的时候,就会执行swapper,这就是对应的空闲任务
对应的,在perf report的界面,展开对应的调用栈,可以看到swapper时钟事件都耗费在了do_idle上,就是空闲任务的执行
10.perf中,前两列children和self两个指标各自代表说明呢?
Self是最后一列的函数本身所占的比例
Children是这个符号调用其他的符号占用的比例之和
最后说明一下perf这种动态最终的工具,会给系统带来一定的性能损失
而vmstat pidstat这种直接去读proc文件系统来获取指标的工具,并不会带来性能损失