良久没写技术文章了,当天任务“早”,便捷叨叨一篇。
早任务的要素说起来也有点搞笑,是由于健身时刻杠铃把手上砸了个口子。砸伤过后我看了一眼,只管很痛但骨头没事,居然心中还有一丝庆幸。缝针吧,有点夸张,不处置吧,还挺深。于是,我在从医院处置完伤口后,有了这篇文章。
好了,言归正传。
CPU 升高疑问案例
市面上通常关于 CPU 疑问排查的案例面试比拟少,基本上都在讲:假设 CPU 升到 100% 怎样办?
这确实是个高频疑问,必定须要晦涩回答。之前也写过一篇文章,可以参考:
重点疑问!CPU应用率过高排查思绪|原创
真实案例
这是一个当天出现的真实案例(相关信息已脱敏处置,不影响案例实质)。
疑问如下:这是一个比拟大名目改变,变革的环节中触及到了相当多下游接口的改变和相当多的依赖包。当天在上线颁布后经过接口和配置验证,需求颁布成功。
然而接着,我颁布成功后才发现机器的平均 CPU 负载升高,平均 CPU 负载简直升高了有 5-8 %,最高负载更是超越了 CPU 安保水位线。如此多的改变,究竟是什么造成了 CPU 负载的回升?
我自己用 python 花了张图,大略上方这个样子
疑问出现,CPU升高
留意:颁布环节中出现任何疑问不要想排查疑问要素,间接回滚,血泪经验的铁律
排查疑问
我排查疑问的思绪如下:
疑问引入的依赖有很多,究竟是哪个依赖引入的?我难道一个个下掉去排查吗?
扫除法,这也确实是一种方法,只不过是太辛劳了,事半功倍。更不用说还须要下掉相关代码,还得不时去耗时颁布,真实是繁琐。
怎样办呢?不卖关子了,间接上 Arthas。
Async-profiler
Arthas经常使用async-profiler生成 CPU/内存火焰图启动性能剖析,补偿了之前内存剖析的无余。
async-profiler 是一款开源的 Java 性能剖析工具,原理是基于 HotSpot 的 API,以微缺乏道的性能开支搜集程序运转中的堆栈信息、内存调配等信息启动剖析。
官方:
咱们罕用的是 CPU 性能剖析和 Heap 内存调配剖析。在启动 CPU 性能剖析时,仅须要十分低的性能开支就可以启动剖析。
在启动 Heap 调配剖析时,async-profiler 工具会搜集内存调配信息,而不是去检测占用 CPU 的代码。async-profiler 不经常使用侵入性的技术,例如字节码检测工具或许探针检测等,这也说明 async-profiler 的内存调配剖析像 CPU 性能剖析一样,不会发生太大的性能开支,同时也不用写出宏大的堆栈文件再去进后退一步处置,。
async-profiler 工具在采样后可以生成采样结果的日志报告,也可以生成 SVG 格局的火焰图。
详细经常使用大家间接去官方看文档吧,有疑问留言。我这里间接说经常使用
经常使用 async-profiler 排查疑问
进入测试主机控制台,经常使用 JPS 命令检查 PID 信息。
➜develop jps Jps TestCode Launcher
假定运转程序的名是 TestCode,可以看到对应的 PID 是 528。
经常使用上方命令:
profilersh d f svg
对 528 号进程采样20秒,而后获取生成的 528.svg 文件,而后咱们经常使用阅读器关上这个文件,可以看到 CPU 的经常使用火焰图,如下(这里用网络图片替代):
关于火焰图怎样看,一言以蔽之:火焰图里,横条越长,代表经常使用的越多,从下到上是调用堆栈信息。在这个图里可以看到 main 方法上方的调用中 hotmethod3 方法的 CPU 经常使用是最多的,点击这个方法。还或许看到更详细的信息。
那么咱们如今只有要查找hotmethod3 经常使用的中央在哪里,就可以定位到疑问代码。
当然,上方的是个替代 case,通知你怎样看这个火焰图。真实的 case 要比这个更难排查。如下图,疑问代码是个线程,是由某个类调用的:
排查疑问依赖引入
疑问代码是一个 Thread 的 run 方法惹起的,那么是谁调用的他呢?这个类的信息我打码了,假定为 ClassA。
然而排查代码,ClassA 基本没有被名目代码间接的调用,于是我找到了这个 CalssA 所属的依赖包 dep-demoA,看他是谁引入的。
gradlew :名目名:dependencyInsight
这个命令会打出一个名目标依赖树,结果如下:
如上结果,名目中我是用的是 dep-demoC,结果他同时引入了 dep-demoB,我看了下这个 demoB,他很或许会跟 arthas 相似,经过 JavaAgent技术和字节码增强技术以成功必定的配置,这对程序是十分有损耗的。(所以线上不能开 arthas)
尝试扫除 demoB,代码如下:
exclude : module:
而后重启名目,CPU 负载降低,回归到反常水平,疑问处置。