java高级开发

【Arthas】基本使用

2024-01-31  本文已影响0人  老鼠AI大米_Java全栈

接口响应不符合预期,怀疑参数没传正确或者接口响应慢等问题,按以前的做法是在程序中打印日志记录入参、响应时间再进行部署,整个过程耗时长,通过 Arthas Java应用诊断利器,可以直接在线上拦截接口入参,排查各方法耗时等问题

使用场景

主要的场景如下:

  1. 是否需要一个全局视角来查看系统的运行状况?
  2. 系统CPU升高了,到底是哪里占用了CPU?
  3. 运行的多线程有死锁吗?有阻塞吗?
  4. 有什么方法可以监控到JVM的实时运行状态?

安装

可以在官方 Github 上进行下载,也可以在国内的码云 Gitee 下载。

github下载
wget https://alibaba.github.io/arthas/arthas-boot.jar

Gitee 下载
wget https://arthas.gitee.io/arthas-boot.jar

打印帮助信息
java -jar arthas-boot.jar -h

运行

java -jar arthas-boot.jar 9557

image.png

常用命令

image.png

dashboard

image.png

首先我们可以通过dashboard查看线程整体的运行情况,heap的消耗情况,以及运行时环境

thread 查看所有线程的状态

image.png

threa id:查看具体某一个线程的具体信息


image.png

sc & sm

sc: search class
sm: search method

image.png
image.png

monitor:方法的执行监控

image.png

trace: 查看方法中方法的耗时

[arthas@5555]$ trace --skipJDKMethod false demo.MathGame run

PrintStream 类的 print 方法占据了 87% 的时间,这是 JDK 自带的类,这说明我们程序本身并无耗时问题,但 MathGame 类的 primeFactors 方法抛出了异常,我们可以看看具体的异常,再思考怎么优化。


image.png

另外,trace 可以选择性地进行调用拦截,比如设置只拦截大于 20ms 的调用:

[arthas@5555]$ trace demo.MathGame run '#cost > 20'

image.png

使用ognl进行条件过滤


image.png

watch:观测函数的调用情况

watch 查看真实的调用数据
拦截 primeFactors 方法抛出的异常:

$ watch demo.MathGame primeFactors -e "throwExp"

image.png

小王从大到小、逐步分析,找出了问题的原因是 primeFactors 抛出了异常,修正参数后,程序恢复了正常。

image.png

tt

tt: Time Tunnel.记录下当前方法的每次调用环境现场
tt -t:记录调用信息


image.png

tt -i: 显示某次调用的详细信息


image.png
tt -l: List all the time fragments
image.png
tt -i [index] -p: 重做一次调用
image.png

profile 明确整体的耗时情况

profile 命令支持为应用生成火焰图,在 Arthas 终端输入以下命令:

开始对应用中当前执行的活动采样 30 秒,采样结束后默认会生成 HTML 文件

[arthas@5555]$ profiler start -d 30

打开 HTML 文件能看到这样的结构:


image.png

MathGame 类下的 run 方法占用了大部分的执行时间,接下来我们看看 run 方法内部的耗时情况。

CPU 占用过高

CPU 是程序运行的核心计算资源,一旦出现 CPU 占用过高,必定对大部分用户的访问耗时产生影响。针对这类问题,要定位出有问题的线程,并获取该线程当前执行的代码位置。

使用 top + jstack 命令可以定位这类问题(见参考资料三),Arthas 也提供了更便捷的一体化工具:

  1. 定位目标线程

调用线程看板,并刷新数据三次

[arthas@5555]$ dashboard -n 3

image.png

DashBoard 刷新三次后,在最新状态中发现示例程序里自己的线程 “main” 占用不算高,说明程序运行正常。如果是要排错,这里就要找出 CPU 占用最高的用户线程的 ID。

  1. 查看目标线程执行的代码位置

“1” 是上一步定位到的 main 的线程ID
[arthas@5555]$ thread 1

image.png

线程正在“睡觉”,没什么大问题。

生产环境的效果和测试不一样

有些时候你发现:测试环境正常,但生产就报错了。这类问题主要靠做好上线流程的管控,但也有可能是打包的依赖库出现冲突,造成程序行为不一致。接下来,我们看看怎么用 Arthas 反编译代码,以及怎么对比依赖库的版本。

  1. 反编译代码

demo.MathGame 是目标类的全限定名
[arthas@5555]$ jad demo.MathGame

image.png
  1. 查看目标类所属的依赖包

demo.MathGame 是目标类的全限定名
[arthas@5555]$ sc -d demo.MathGame

image.png

如果这里是依赖包,code-source 还可以显示所属包的版本。这样就可以对比本地的代码,从而在打包时设置正确的依赖版本。

内存溢出

生产问题中内存溢出也有不小的比例。内存溢出的关键是找出高内存占用的对象。命令行操作会比较麻烦,建议转储 Heap Dump 等文件后,通过 Eclipse Memory Analyzer(MAT) 等工具进行分析。

通过 IDEA 插件快速生成 Arthas 命令

image.png

通过插件快速生成【拦截方法入参、返回值】命令


image.png

打开命令行下载并启动 Arthas,看到下面页面时选择相应的进程进行拦截,这里按 1 并按回车键完成


image.png
粘贴上面插件生成的 Arthas 命令,请求接口便可看到接口入参、返回值
image.png
分析方法调用耗时,使用 Arthas IDEA 插件选择【Trace】命令
image.png

在 Arthas 命令行上粘贴命令并请求接口,方法内部调用路径,并输出方法路径上的每个节点上耗时


image.png
上一篇下一篇

猜你喜欢

热点阅读