乐趣区

关于云计算:定位任意时刻性能问题持续性能分析实践解析

01 继续性能分析简介

更好的利用性能,能够提供更好的用户体验,能够升高企业 IT 老本,能够让零碎更稳固和牢靠。在利用性能分析技术呈现以前,开发人员排查问题只能依赖各种日志和监控,这须要提前在利用代码中埋点,岂但对利用代码侵入性较大且可能因为埋点不全而无奈提供足够信息,诊断问题十分费时,很多时候无奈找出起因。

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

近些年来,性能分析技术继续倒退,性能越来越丰盛,开销也显著改善,达到生产环境继续开启水准,不过离宽泛遍及还存在诸多阻碍。性能分析个别过程有三步:生产环境抓取、保留性能分析文件、性能分析文件可视化。当利用体量较大时,这 3 个步骤每步都存在着难度,须要解决大量计算、存储、产品设计等多方面问题。

ARMS Continuous Profiler[1]应运而生,由阿里云 ARMS(利用实时监控服务 [2])团队和 Dragonwell[3] 团队联结研发。它基于以后最成熟的性能分析技术,将整个性能分析过程产品化,适宜在生成环境继续开启。与惯例性能分析相比,ARMS Continuous Profiler 减少工夫维度,外围性能如下:

  • 定位任意时刻的性能问题(比方 CPU 占用高、内存占用高)
  • 反对两个时段的性能比照,找出利用演进过程中的性能差别
  • 观测利用的调用栈,以便更好的扫视和了解代码设计

02 ARMS 继续性能剖析性能演示

咱们举例来说明如何用 ARMS 继续性能剖析来解决问题。

常见场景一:CPU 热点解析

  • 问题景象

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

  • 找出热点办法

因为以后利用 CPU 占用很高,因而咱们间接在性能剖析类型中抉择 CPU Time 菜单门路:ARMS 控制台 -> 利用首页 -> 利用诊断 -> CPU& 内存诊断

从火焰图咱们能够看到,java.util.LinedList.node(int)办法占用了 85% 的 CPU,对应的业务代码办法是 DemoController.countAllBookPages(List),联合代码,能够发现,这个办法对于对象很多的汇合性能很差,因为要从头或者从尾部一一遍历。

  • 修复问题

定位到起因后,咱们能够通过两个解决方案进行修复。第一个办法是将 LinkedList 批改为下标拜访形式更高效的 ArrayList

第二个办法是将 LinkedList 的遍历算法从一般 for 循环批改为加强的 for 循环

  • 性能验证

将修复后的代码重新部署,以雷同压力别离压测两种计划,能够看到接口响应工夫显著降落,Java 过程 CPU 利用率显著降落。

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

  • 问题景象

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

  • 找出热点办法

因为以后利用 CPU 占用很高,咱们间接在性能剖析类型中抉择:CPU Time 菜单门路:ARMS 控制台 -> 利用首页 -> 利用诊断 -> CPU& 内存诊断

从 CPU 热点办法,咱们发现 Java 过程 89% 的工夫都在做 GC,阐明利用存在很大的内存压力。咱们下一步抉择内存热点分析。

从上图的内存申请热点火焰图,咱们能够找到过来一段时间所有内存申请中,DemoController.queryAllBooks 办法占了 99%,进一步查看,能够发现业务代码创立了 2 万个大对象并保留到了 List。

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

  • 修复问题

这个接口原本想实现的是按分页查问书籍列表,但因为实现谬误,误将所有书籍都查出来了而后最终只返回了指定分页的局部,所以能够间接从数据库中用分页的形式查问,这样就能够防止大量的 Java 内存占用。

  • 性能验证

将修复后的代码重新部署,以前雷同压力进行压测,能够看到接口响应工夫显著降落,Java 过程 CPU 利用率显著降落。

03 ARMS 继续性能剖析的设计和实现

1、产品设计

产品整体分为 3 个局部,第一个局部负责在利用端收集性能分析数据,第二个局部用于传输和存储分析后果文件,第三局部用于查问和展现。

第一个局部次要应用 Java Flight Recorder[4]、async-profiler[5],咱们会依据 Java 版本状况主动抉择其一,其外围性能是周期性对应用程序进行采样,并且不会因为平安点问题导致后果不精确。下图是对一个线程采样 6 次的例子,能够看到每次采样霎时的调用栈。最终保留为 JFR 格局的文件。

第二个局部比拟重要的是 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 阶段、耗时。

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,因为文件格式雷同,所以剖析和存储计划都能够复用。

4、JFR File Analyzer

JFR File Analyzer 的输出是 JFR 文件,输入是一种反对按工夫范畴高效查问的树状构造。一个 JFR 文件中能够蕴含 CPU 热点、内存申请热点等多个方面的数据,每个方面都有对应的解析和存储实现。

04 总结

本文介绍了继续性能分析的产生背景,通过两个例子演示了 ARMS Continuous Profiler 的理论应用场景,也对 ARMS Continuous Profiler 的设计和外围模块进行了介绍,其次要特点如下:

05 相干链接

[1] ARMS Continuous Profilerhttps://help.aliyun.com/document_detail/473143.html
[2] 利用实时监控服务 https://help.aliyun.com/product/34364.html
[3] Dragonwellhttps://dragonwell-jdk.io/#/index
[4] Java Flight Recorderhttps://docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-gu…
[5] async-profilerhttps://github.com/async-profiler/async-profiler

作者:义泊

原文链接

本文为阿里云原创内容,未经容许不得转载。

退出移动版