定位任意时刻性能问题,持续性能分析实践解析

本文涉及的产品
可观测监控 Prometheus 版,每月50GB免费额度
可观测可视化 Grafana 版,10个用户账号 1个月
性能测试 PTS,5000VUM额度
简介: 定位任意时刻性能问题,持续性能分析实践解析

作者:义泊


01 持续性能剖析简介


更好的应用性能,可以提供更好的用户体验,可以降低企业IT成本,可以让系统更稳定和可靠。在应用性能剖析技术出现以前,开发人员排查问题只能依赖各种日志和监控,这需要提前在应用代码中埋点,不但对应用代码侵入性较大且可能由于埋点不全而无法提供足够信息,诊断问题非常费时,很多时候无法找出原因。


随着应用性能剖析技术出现,开发人员可以很方便的找出应用程序性能瓶颈(如CPU利用率高、内存占用高等),从而进行优化。但由于早期应用性能剖析技术开销较大,只能在开发环境而不能在生产长时间开启,生产环境出问题时很可能没有被记录下来,开发人员在开发环境模拟和复现问题很困难,导致解决问题的效率很低,也很有可能无法解决。


近些年来,性能剖析技术持续发展,功能越来越丰富,开销也显著改善,达到生产环境持续开启水准,不过离广泛普及还存在诸多障碍。性能剖析一般过程有三步:生产环境抓取、保存性能剖析文件、性能剖析文件可视化。当应用体量较大时,这3个步骤每步都存在着难度,需要解决大量计算、存储、产品设计等多方面问题。


ARMS Continuous Profiler[1]应运而生,由阿里云ARMS(应用实时监控服务[2])团队和Dragonwell[3]团队联合研发。它基于当前最成熟的性能剖析技术,将整个性能剖析过程产品化,适合在生成环境持续开启。与常规性能剖析相比,ARMS Continuous Profiler增加时间维度,核心功能如下:

  • 定位任意时刻的性能问题(比如CPU占用高、内存占用高)
  • 支持两个时段的性能对比,找出应用演进过程中的性能差异
  • 观测应用的调用栈,以便更好的审视和理解代码设计


02 ARMS 持续性能分析功能演示


我们举例来说明如何用ARMS持续性能分析来解决问题。


常见场景一:CPU 热点解析

  • 问题现象

以某图书馆的服务应用举例,其Java进程占用大量CPU,接口响应时间达到了十多秒,应用性能很差。

image.png

image.png

image.png

  • 找出热点方法

因为当前应用CPU占用很高,因此我们直接在性能分析类型中选择CPU Time菜单路径:ARMS控制台 -> 应用首页 -> 应用诊断 -> CPU&内存诊断

image.png

image.png

从火焰图我们可以看到,java.util.LinedList.node(int)方法占用了85%的CPU,对应的业务代码方法是DemoController.countAllBookPages(List),结合代码,可以发现,这个方法对于对象很多的集合性能很差,因为要从头或者从尾部逐个遍历。image.png

  • 修复问题

定位到原因后,我们可以通过两个解决方案进行修复。第一个方法是将LinkedList修改为下标访问方式更高效的ArrayList

image.png

第二个方法是将LinkedList的遍历算法从普通for循环修改为增强的for循环

image.png

  • 性能验证

将修复后的代码重新部署,以相同压力分别压测两种方案,可以看到接口响应时间显著下降,Java进程CPU利用率显著下降。

image.png

image.png


常见场景二:内存申请热点

  • 问题现象

以某图书馆的服务应用举例,其Java进程占用大量CPU,接口响应时间达到十多秒,应用性能很差。

image.png

image.png

image.png


  • 找出热点方法

因为当前应用CPU占用很高,我们直接在性能分析类型中选择:CPU Time菜单路径:ARMS控制台 -> 应用首页 -> 应用诊断 -> CPU&内存诊断

image.png

image.png

从CPU热点方法,我们发现Java进程89%的时间都在做GC,说明应用存在很大的内存压力。我们下一步选择内存热点剖析。

image.png

image.png

从上图的内存申请热点火焰图,我们可以找到过去一段时间所有内存申请中,DemoController.queryAllBooks方法占了99%,进一步检查,可以发现业务代码创建了2万个大对象并保存到了List。

注:这个方法本来应该从数据库中读取2万本书,这里进行了简化,但效果相同,都是在堆中创建了一个占用大量内存的List

image.png

  • 修复问题

这个接口本来想实现的是按分页查询书籍列表,但由于实现错误,误将所有书籍都查出来了然后最终只返回了指定分页的部分,所以可以直接从数据库中用分页的方式查询,这样就可以避免大量的Java内存占用。

image.png

  • 性能验证

将修复后的代码重新部署,以前相同压力进行压测,可以看到接口响应时间显著下降,Java进程CPU利用率显著下降。

image.png03

image.png


03 ARMS 持续性能分析的设计和实现


1、产品设计

产品整体分为3个部分,第一个部分负责在应用端收集性能剖析数据,第二个部分用于传输和存储剖析结果文件,第三部分用于查询和展示。

image.png

第一个部分主要使用Java Flight Recorder[4]async-profiler[5],我们会根据Java版本情况自动选择其一,其核心功能是周期性对应用程序进行采样,并且不会因为安全点问题导致结果不准确。下图是对一个线程采样6次的例子,可以看到每次采样瞬间的调用栈。最终保存为JFR格式的文件。

image.png

第二个部分比较重要的是JFR Analyzer,其核心功能是读取JFR文件,对其进行解析、计算和聚合,最终生成便于查询和展示的中间结果。第三个部分的核心功能是将剖析结果展示为表格或火焰图,也要支持对比能力。

2、Java Flight Recorder

JFR是OpenJDK内置的低开销监控和性能剖析工具,深度集成在虚拟机各个角落。当Oracle在OpenJDK11上开源JDK Flight Recorder之后,阿里巴巴也是作为主要贡献者,与RedHat等社区贡献者一起将 JFR 移植到OpenJDK 8。


JFR由两个部分组成:第1个部分分布在虚拟机各个关键路径上,负责捕获信息。

第2个部分是虚拟机内单独模块,负责接收和存储第1个部分产生的数据,这些数据通常也叫做事件。

JFR包含160种以上事件,JFR事件包含很多有用的上下文信息及时间戳。比如方法执行调用栈、文件访问、特定GC阶段的发生,或特定GC阶段、耗时。

image.png

image.png


3、async-profiler

async-profiler是一个低开销的Java性能剖析工具,依靠JVM的特定API进行CPU和内存申请的剖析。


因为OracleJDK 8上JFR功能是商业特性,所以在OracleJDK8上我们用async-profiler作为替换技术,实现相同剖析能力。而对于OpenJDK8,由于内存申请热点剖析功能存在较大性能开销,我们也用async-profiler作为替代技术。


async-profiler使用C++开发,以动态库方式加载到JVM进程中,支持生成JFR格式文件,这样不论我们用JFR还是async-profiler,因为文件格式相同,所以分析和存储方案都可以复用。

image.png

4、JFR File Analyzer

JFR File Analyzer的输入是JFR文件,输出是一种支持按时间范围高效查询的树状结构。一个JFR文件中可以包含CPU热点、内存申请热点等多个方面的数据,每个方面都有对应的解析和存储实现。

image.png04

04 总结


本文介绍了持续性能剖析的产生背景,通过两个例子演示了ARMS Continuous Profiler的实际使用场景,也对ARMS Continuous Profiler的设计和核心模块进行了介绍,其主要特点如下:

image.png

image.png

对ARMS Continuous Profiler感兴趣的读者,可以加入专属服务钉群,或者阅读产品文档,欢迎试用和交流。

👉 专属服务钉群:22560019672

image.png

📒 文档:https://help.aliyun.com/document_detail/473143.html05


05 相关链接


[1] ARMS Continuous Profiler

https://help.aliyun.com/document_detail/473143.html

[2] 应用实时监控服务

https://help.aliyun.com/product/34364.html

[3] Dragonwell

https://dragonwell-jdk.io/#/index

[4] Java Flight Recorder

https://docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-guide/about.htm

[5] async-profiler

https://github.com/async-profiler/async-profiler

image.png

相关文章
|
26天前
|
存储 缓存 安全
Java内存模型深度解析:从理论到实践####
【10月更文挑战第21天】 本文深入探讨了Java内存模型(JMM)的核心概念与底层机制,通过剖析其设计原理、内存可见性问题及其解决方案,结合具体代码示例,帮助读者构建对JMM的全面理解。不同于传统的摘要概述,我们将直接以故事化手法引入,让读者在轻松的情境中领略JMM的精髓。 ####
33 6
|
23天前
|
运维 持续交付 云计算
深入解析云计算中的微服务架构:原理、优势与实践
深入解析云计算中的微服务架构:原理、优势与实践
56 1
|
1月前
|
消息中间件 存储 缓存
十万订单每秒热点数据架构优化实践深度解析
【11月更文挑战第20天】随着互联网技术的飞速发展,电子商务平台在高峰时段需要处理海量订单,这对系统的性能、稳定性和扩展性提出了极高的要求。尤其是在“双十一”、“618”等大型促销活动中,每秒需要处理数万甚至数十万笔订单,这对系统的热点数据处理能力构成了严峻挑战。本文将深入探讨如何优化架构以应对每秒十万订单级别的热点数据处理,从历史背景、功能点、业务场景、底层原理以及使用Java模拟示例等多个维度进行剖析。
54 8
|
15天前
|
机器学习/深度学习 人工智能 算法
深入解析图神经网络:Graph Transformer的算法基础与工程实践
Graph Transformer是一种结合了Transformer自注意力机制与图神经网络(GNNs)特点的神经网络模型,专为处理图结构数据而设计。它通过改进的数据表示方法、自注意力机制、拉普拉斯位置编码、消息传递与聚合机制等核心技术,实现了对图中节点间关系信息的高效处理及长程依赖关系的捕捉,显著提升了图相关任务的性能。本文详细解析了Graph Transformer的技术原理、实现细节及应用场景,并通过图书推荐系统的实例,展示了其在实际问题解决中的强大能力。
104 30
|
15天前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
83 14
|
19天前
|
存储 算法
深入解析PID控制算法:从理论到实践的完整指南
前言 大家好,今天我们介绍一下经典控制理论中的PID控制算法,并着重讲解该算法的编码实现,为实现后续的倒立摆样例内容做准备。 众所周知,掌握了 PID ,就相当于进入了控制工程的大门,也能为更高阶的控制理论学习打下基础。 在很多的自动化控制领域。都会遇到PID控制算法,这种算法具有很好的控制模式,可以让系统具有很好的鲁棒性。 基本介绍 PID 深入理解 (1)闭环控制系统:讲解 PID 之前,我们先解释什么是闭环控制系统。简单说就是一个有输入有输出的系统,输入能影响输出。一般情况下,人们也称输出为反馈,因此也叫闭环反馈控制系统。比如恒温水池,输入就是加热功率,输出就是水温度;比如冷库,
137 15
|
22天前
|
弹性计算 持续交付 API
构建高效后端服务:微服务架构的深度解析与实践
在当今快速发展的软件行业中,构建高效、可扩展且易于维护的后端服务是每个技术团队的追求。本文将深入探讨微服务架构的核心概念、设计原则及其在实际项目中的应用,通过具体案例分析,展示如何利用微服务架构解决传统单体应用面临的挑战,提升系统的灵活性和响应速度。我们将从微服务的拆分策略、通信机制、服务发现、配置管理、以及持续集成/持续部署(CI/CD)等方面进行全面剖析,旨在为读者提供一套实用的微服务实施指南。
|
16天前
|
存储 缓存 Python
Python中的装饰器深度解析与实践
在Python的世界里,装饰器如同一位神秘的魔法师,它拥有改变函数行为的能力。本文将揭开装饰器的神秘面纱,通过直观的代码示例,引导你理解其工作原理,并掌握如何在实际项目中灵活运用这一强大的工具。从基础到进阶,我们将一起探索装饰器的魅力所在。
|
16天前
|
机器学习/深度学习 搜索推荐 API
淘宝/天猫按图搜索(拍立淘)API的深度解析与应用实践
在数字化时代,电商行业迅速发展,个性化、便捷性和高效性成为消费者新需求。淘宝/天猫推出的拍立淘API,利用图像识别技术,提供精准的购物搜索体验。本文深入探讨其原理、优势、应用场景及实现方法,助力电商技术和用户体验提升。
|
23天前
|
安全 持续交付 Docker
深入理解并实践容器化技术——Docker 深度解析
深入理解并实践容器化技术——Docker 深度解析
43 2

推荐镜像

更多
下一篇
DataWorks