我是如何通过火焰图分析让应用CPU占用下降近20%的

简介: 分享作者在使用Arthas火焰图工具进行Java应用性能分析和优化的经验。

看到标题是不是很多人在想是不是标题党了,是也不是👻~,请听我细细道来~


我们的应用代码是用Java写的,因此使用的火焰图工具是Arthas,下面的分析也是基于此。


Arthas火焰图使用

官方文档:https://arthas.aliyun.com/doc/profiler.html


启动火焰图分析

$ profiler start
Started [cpu] profiling


停止

$ profiler stop --format flamegraph
profiler output file: /tmp/test/arthas-output/20211207-111550.html
OK

如上所示默认会生成一个html的火焰图文件,指定输出格式相关可参考官方文档。


火焰图示例

image.png

火焰图横轴代表CPU的占用时间,横轴越宽代表CPU占用越多,鼠标移动上去也可以看到这个方法究竟占用了多少CPU。


纵轴代表调用栈,火焰越高代表调用栈越深。


其中绿色部分代表Java代码,黄色部分代表JVM C++代码,橙色部分代表内核态C语言代码,红色代表用户态C语言代码。


如何分析火焰图(附实战)


事情是这样的,我们的业务简单来说就是监听发货消息后执行一系列操作,分自动和批量两种方式,批量的大用户进行业务操作时,会同时有几万单、十几万单的产生,相当于大促时的流量了,因此cpu占用总是有尖刺,有时单机甚至能到80+%。而且日常流量时感觉cpu占用和流量数据相比也有些偏高,因此决定使用火焰图分析下。


从上往下看

下面采用两个在优化过程中比较典型的两个案例。

案例一

image.png

火焰图分析最简单的方式就是找大平顶,如果一个方法占用比较耗时、调用次数很多,那么他的横轴一定是比较宽的,体现到火焰图上就是一个大平顶。


图中红框是业务代码的执行,其中蓝框是初步定位到的耗时操作,点开后可以看到左侧是sentinel采样CPU占用,占用总CPU3%~4%,这部分应该是不会随流量上升而升高的, 这次就先没有动这块。第二块是在metaq的消费者代码里执行的,因此重点关注,因为我们的应用是消息驱动的,接受tp的发货消息后进行对应的操作,metaq流量升高,这部分对应的操作大概率也是会随之升高的。

image.png

image.png

占总CPU占用达到了惊人的9.3%。


点开后可以看到是脱敏工具,其对性能的影响几乎和发货消息齐平了,排查后发现是我们部门内部使用的链路采集工具,在采集metaq消息时会对消息进行脱敏处理,脱敏工具会对姓名、邮箱、手机号等分别进行正则匹配,而我们接收的交易消息中是包含整个订单信息的,这个对象是很大的(包含扩展字段等诸多信息),对其使用正则进行脱敏工作量巨大。正常情况下使用此工具采集线上流量对性能影响不是很大,但是在我们的场景影响有点出乎意料......


由于我们平时基本不会在链路图上关注消息的内容,一般都是用来看HSF链路,因此直接把dp对metaq的采集关闭了。

案例二

image.png

image.png


使用全局搜索后居然占用了将近6%的CPU,这可是日常的流量下截取的火焰图,系统流量升高时占用比例会更大。


点开后可以看到是进行HSF调用的时候,获取Java调用栈比较耗时,之前写代码的时候怀疑过获取调用栈会比较耗性能,但没想到居然比一次HSF调用本身的耗时都大了。这个地方之前是为了获取调用来源,打印到日志中方便排查问题的(历史代码),后续将HSF的调用日志改成了通过HSF Filter的方式,去掉了获取调用栈的逻辑。


其实案例二我一开始不是从上往下看定位到的,因为调用HSF的地方不止一个,每个耗时其实也不长,整体看的话从上往下还是比较难发现的。


从下往上看

案例二

如果从上往下看效果不明显,可以从我们系统主要流量入口处进行分析,从下面入口一步步往上点,也可以发现问题,带着怀疑的态度来找,上述的案例二我一开始并没有注意到上方的问题,我是一步步从消息入口看,然后点到上面发现的这个调用消耗居然比HSF多的。

image.png

可以看到这个调用不是集中在一个地方的,细看每个地方都有调用,所以整体对性能的影响才那么大。


全局搜索后可以看到到处都有调用(图示紫色部分)。

image.png

从下往上找更适合细化的时候,专门对某个链路进行分析优化。


优化效果

下面来让我们计算一下数据,来看看楼主是不是标题党了。

image.png

整体大致优化了5~6%左右(7月份的时候,机器数量是30台,8月缩容到了27台),取5%,其中系统CPU占用在6.5%左右,从日常流量上来看,用户态cpu从26%到21%,下降19%+,考虑缩容的关系,20%的优化大抵是有的👻。


由于这是日常流量的优化结果,大促流量突增时,系统负载降低应该会更明显,优化后大用户批量操作时瞬时流量也基本不会有机器cpu占用超过60%了。


后续双十一压测也会继续关注优化,流量上升后更多问题可能就会暴露出来。







来源  |  阿里云开发者公众号
作者  |  誉铭



相关文章
|
1月前
线程CPU异常定位分析
【10月更文挑战第3天】 开发过程中会出现一些CPU异常升高的问题,想要定位到具体的位置就需要一系列的分析,记录一些分析手段。
61 0
|
1月前
|
监控 并行计算 数据处理
构建高效Python应用:并发与异步编程的实战秘籍,IO与CPU密集型任务一网打尽!
在Python编程的征途中,面对日益增长的性能需求,如何构建高效的应用成为了每位开发者必须面对的课题。并发与异步编程作为提升程序性能的两大法宝,在处理IO密集型与CPU密集型任务时展现出了巨大的潜力。今天,我们将深入探讨这些技术的最佳实践,助你打造高效Python应用。
37 0
|
28天前
|
运维 JavaScript Linux
容器内的Nodejs应用如何获取宿主机的基础信息-系统、内存、cpu、启动时间,以及一个df -h的坑
本文介绍了如何在Docker容器内的Node.js应用中获取宿主机的基础信息,包括系统信息、内存使用情况、磁盘空间和启动时间等。核心思路是将宿主机的根目录挂载到容器,但需注意权限和安全问题。文章还提到了使用`df -P`替代`df -h`以获得一致性输出,避免解析错误。
|
4月前
|
运维 监控 Linux
解决CPU与带宽高使用率问题:深入分析与应对策略
引言:性能问题的诊断与优化 在运维工作中,操作系统性能问题如影随形,典型代表是CPU使用率高和带宽使用率高的问题,它们直接影响应用的性能和响应时间。这篇记录将逐个分析这两个问题的产生原因和解决方法。
解决CPU与带宽高使用率问题:深入分析与应对策略
|
4月前
|
监控 算法 Java
|
4月前
|
并行计算 监控 数据处理
构建高效Python应用:并发与异步编程的实战秘籍,IO与CPU密集型任务一网打尽!
【7月更文挑战第16天】Python并发异步提升性能:使用`asyncio`处理IO密集型任务,如网络请求,借助事件循环实现非阻塞;`multiprocessing`模块用于CPU密集型任务,绕过GIL进行并行计算。通过任务类型识别、任务分割、避免共享状态、利用现代库和性能调优,实现高效编程。示例代码展示异步HTTP请求和多进程数据处理。
56 8
|
4月前
|
监控 算法 Java
压测分析Java内存和CPU暂用
7月更文挑战第7天
67 5
|
8天前
|
弹性计算 Kubernetes Perl
k8s 设置pod 的cpu 和内存
在 Kubernetes (k8s) 中,设置 Pod 的 CPU 和内存资源限制和请求是非常重要的,因为这有助于确保集群资源的合理分配和有效利用。你可以通过定义 Pod 的 `resources` 字段来设置这些限制。 以下是一个示例 YAML 文件,展示了如何为一个 Pod 设置 CPU 和内存资源请求(requests)和限制(limits): ```yaml apiVersion: v1 kind: Pod metadata: name: example-pod spec: containers: - name: example-container image:
|
17天前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
191 2
|
2月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
128 5