拯救Java应用:Arthas监控术,让你事半功倍

背景

想象一下,您的Java应用突然出现性能问题,用户投诉不断,而您却无法快速定位问题所在。传统的监控工具只提供了有限的信息,真正的故障元凶似乎总是遥不可及。现在,让我们揭开Arthas的神秘面纱——这个强大的Java诊断工具能够帮助开发者在复杂的应用中找到那些隐藏的性能瓶颈和棘手的bug。从实时监控方法调用到追踪JVM内部状态,Arthas提供了前所未有的洞察力,让您能够以最小的侵入性检查运行中的应用。加入我们,深入了解Arthas如何让Java应用变得透明,并帮助您在开发和维护过程中节省宝贵的时间。

介绍

Arthas 是由Alibaba开源的一款监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。

Arthas能为你做什么

Arthas 是 Alibaba 开源的 Java 诊断工具,深受开发者喜爱。当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

  • 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  • 有什么办法可以监控到 JVM 的实时运行状态?
  • 怎样直接从 JVM 内查找某个类的实例?
  • 如何查看当前线程信息,查看线程的堆栈?
  • 接口耗时时间长?到底问题出在哪里?哪个方法慢呢?
  • 怎样直接从 JVM 内查找某个类的实例?
  • 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?

Arthas环境要求

支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式。

Arthas安装方式

  1. 下载arthas-boot.jar,然后用java -jar的方式启动:
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

如果你出现了这个页面,表示启动成功了。

  1. Arthas Spring Boot Starter

提示:只支持 spring boot 2。应用启动后,spring 会启动 arthas,并且 attach 自身进程。

<dependency>
  <groupId>com.taobao.arthas</groupId>
	<artifactId>arthas-spring-boot-starter</artifactId>
	<version>${arthas.version}</version>
</dependency>

命令列表

arthas命令有很多,这里我列下常用的一些,如果需要的话,文章结尾我会写出开源地址,大家自己去动手尝试。

  • dashboard

Arthas启动后,我们可以使用仪表盘。在这个例子中,我们通过输入dashboard命令来操作。现在我们可以看到一个详细的屏幕,它包含多个面板和关于我们Java进程的大量信息:

  1. 顶部区域显示当前正在运行的线程。其中一列是显示每个线程的CPU消耗以及显示每个线程的CPU时间。
  2. ˙中间区域显示的是内存分析。列出了不同的内存区域及其统计信息。在右侧,我们有关于垃圾回收器的信息。
  3. 最下面有关于主机平台和JVM的信息。
  • thread

查看当前线程信息,查看线程的堆栈。

这将显示与进程ID为1的线程相关的详细信息,包括线程名称、状态、堆栈跟踪等。通过分析这些信息,我们可以进一步了解导致CPU占用率高的原因,并采取相应的措施来优化性能。

  • jad
反编译指定已加载类的源码。可以反编译类,也可以反编译类中的某个方法,jad demo.MathGame main
  • mc

Memory Compiler/内存编译器,编译.java文件生成.class。可以结合retransform实现热部署。

  • retransform

加载外部的.class文件,retransform jvm 已加载的类。

  • sc

查看 JVM 已加载的类信息,搜索类命令在查找JVM中加载的类时非常有用。我们可以通过输入sc并传递一个带有或不带有通配符的模式作为参数来使用它:

一旦我们获得了类的完全限定名,我们可以使用两个额外的标志来查找更多信息:

-d 用于显示类的详细信息

-f 用于显示类的字段

  • vmtool

vmtool 利用JVMTI接口,实现查询内存对象,强制 GC 等功能。

//vmtool强制 GC
vmtool --action forceGc
  • stack

输出当前方法被调用的调用路径,可以查看方法的调用链

  • trace

方法内部调用路径,并输出方法路径上的每个节点上耗时。这个打印信息是有行数的,便于定位问题。

  • watch

让你能方便的观察到指定函数的调用情况。能观察到的范围为:返回值、抛出异常、入参。下面的结果里,说明函数被执行了两次,第一次结果是location=AtExceptionExit,说明函数抛出异常了,因此returnObj是 null;在第二次结果里是location=AtExit,说明函数正常返回,因此可以看到returnObj结果是一个 ArrayList。

  • monitor

使用Arthas的另一个很酷的功能是监控一个方法。这在我们调试应用程序性能问题时非常方便。为此,我们可以使用monitor命令。monitor命令需要一个标志-c(统计周期) 和两个参数——完全限定的类名和方法名。

监控项说明:timestamp 时间戳、class Java 类、method 方法(构造方法、普通方法)、total 调用次数、success 成功次数、fail 失败次数、rt 平均 RT、fail-rate 失败率

  • tt

方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。这里可以清除的看到方法的耗时。

watch 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。

对于具体一个时间片的信息而言,你可以通过 -i 参数后边跟着对应的 INDEX 编号查看到他的详细信息。

当你稍稍做了一些调整之后,你可能需要前端系统重新触发一次你的调用,此时得求爷爷告奶奶的需要前端配合联调的同学再次发起一次调用。而有些场景下,这个调用不是这么好触发的。

tt 命令由于保存了当时调用的所有现场信息,所以我们可以自己主动对一个 INDEX 编号的时间片自主发起一次调用,从而解放你的沟通成本。此时你需要 -p 参数。通过 --replay-times 指定 调用次数,通过 --replay-interval 指定多次调用间隔(单位 ms, 默认 1000ms)

注意事项:

tt 命令的实现是:把函数的入参/返回值等,保存到一个Map<Integer, TimeFragment>里,默认的大小是 100。

tt 相关功能在使用完之后,需要手动释放内存,否则长时间可能导致OOM。退出 arthas 不会自动清除 tt 的缓存 map。

清除所有的tt记录 tt --delete-all
  • profiler

使用async-profiler生成火焰图

//启动 profiler
profiler start
//获取已采集的 sample 的数量
profiler getSamples
//停止 profiler 转换成HTML
profiler stop --format html

默认情况下,arthas 使用 3658 端口,则可以打开: http://127.0.0.1:3658/arthas-output/ 查看到arthas-output目录下面的 profiler 结果。

开源地址

https://github.com/alibaba/arthas

总结

合适的工具至关重要,能极大地提升工作的效率和质量。大家觉得不错点赞给个关注呗。关注我每天分享不一样的开源软件和服务。

相关文章

Java运行环境配置

若要在计算机上运行Java程序,需要配置Java运行环境(JRE)或Java开发工具包(JDK)。以下是在Windows操作系统上配置Java运行环境的步骤:下载Java安装程序:前往Oracle官方...

第五章:Java方法和参数传递

第五章:Java方法和参数传递在Java编程中,方法是一种重要的概念,它能够将一段代码封装成一个可重复使用的单元。本章将详细介绍Java方法的定义和调用,方法的重载和重写,以及Java中的参数传递方式...

「Java后端」开发环境搭建指南

1. Java1.1 Java安装及配置统一使用Oracle Java,版本为1.8,安装完成后配置环境变量JAVA_HOME及PATH。在命令行执行java -version应显示正确版本号。2....

第十五章:Java测试和调试(完结)

在软件开发的过程中,测试和调试是不可或缺的环节。测试是用于验证程序的正确性和稳定性,而调试则是用于排查和修复程序中的错误。本章将介绍Java中的测试和调试相关的概念、方法、工具和技巧。15.1 Jav...

JVM内存溢出常用排查命令

最近,有一个项目在不超过的12小时内,一定会内存溢出(java.lang.OutOfMemoryError:Java heap space)。由于当时比较忙,没有时间去具体分析,所以暂时只是加大了JV...

JVM常用指令

目录:一.引言二.基础故障处理工具2.1 概述2.2. jps:虚拟机进程状况工具2.3. jstat:虚拟机统计信息监视工具2.3. jinfo:java配置信息工具2.5. jmap:Java...