千家信息网

Java线上诊断工具Arthas的使用方法

发表于:2024-12-01 作者:千家信息网编辑
千家信息网最后更新 2024年12月01日,这篇文章将为大家详细讲解有关Java线上诊断工具Arthas的使用方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。排查一些生产环境问题,确实蛮好用的
千家信息网最后更新 2024年12月01日Java线上诊断工具Arthas的使用方法

这篇文章将为大家详细讲解有关Java线上诊断工具Arthas的使用方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

排查一些生产环境问题,确实蛮好用的。

功能

当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?

  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?

  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?

  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!

  5. 是否有一个全局视角来查看系统的运行状况?

  6. 有什么办法可以监控到JVM的实时运行状态?

使用示例

环境安装

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

上面的启动方式,只能在本地访问。默认的ip是 127.0.0.1,这种情况只命令行交互或者用 http://127.0.0.1:8563/ 来访问。如果想要在别的机器上通过网页的方式访问,可以在启动命令后带上 --target-ip 本机ip,这样就可以在别的机器(前提是机器可以互相访问,且端口是开的)通过网页访问这个 arthas 客户端了。如下:

root@iZuf63uqehzec73094965jZ:/data/arthas# java -jar arthas-boot.jar  --target-ip 139.**.**.112[INFO] arthas-boot version: 3.1.4[INFO] Found existing java process, please choose one and hit RETURN.* [1]: 1701 stock.war  [2]: 15658 /data/secret/web/secret-web.jar2[INFO] arthas home: /root/.arthas/lib/3.1.4/arthas[INFO] Try to attach process 15658[INFO] Attach process 15658 success.[INFO] arthas-client connect 139.**.**.112 3658  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---. /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'wiki      https://alibaba.github.io/arthastutorials https://alibaba.github.io/arthas/arthas-tutorialsversion   3.1.4pid       15658time      2019-10-31 00:16:59

最后可以通过如下方式访问,跟在本机之前敲命令行是一样的。

http://139...112:8563/

trace命令(追踪某个方法的执行耗时情况,支持多方法,时间过滤)

这个命令用来追踪方法的执行性能,支持按照时间过滤,更详细的参考官方文档 trace命令

正常单层跟踪调用链路

命令:

trace com.zero.secret.web.controller.AlbumController home

效果:

结果里面,第一列是该方法的耗时,第二列是具体的方法,第三列是 代码所在的行号

筛选时间

有时候方法内的方法太多,可以根据时间过滤,筛选出超哥某个时间的方法。命令如下:

trace com.zero.secret.web.controller.AlbumController home '#cost > 10'

带上时间过滤测试的没有效果,下次再试试。

深层次跟踪调用链路

trace命令只能跟踪一层,如果想要跟踪更深层的方法,可以用多方法。

trace -E  com.zero.secret.web.controller.AlbumController|com.zero.secret.dal.mapper.AlbumMapper  home|selectByPrimaryKey

注意:

  1. trace本身是有耗时的,这里面显示的耗时没有减去trace本身的耗时

watch命令(支持在线查看变量的值)

详细的watch命令查看官方文档。watch命令

命令:

watch com.zero.secret.service.AlbumService getAlbum "{params,returnObj}" -x 2

这里 -x 2 表示参数深度显示2层,默认只显示一层。下面是一层的返回结果,比对看看

这里入参的值就没有显示出来。

有时候要比对 参数在进入方法之前跟执行方法之后的值,比较着看 参数的值的变化,可以添加参数 -b -s 。命令如下:

watch com.zero.secret.service.AlbumService getAlbum "{params,returnObj}" -x 2 -b -s

结果如下:

这里返回的有两组值。第一组值是进入方法时的入参和返回值,第二组是方法执行结束时的入参和返回值。

stack(查看方法调用链路)

详细stack命令参考官方文档 stack命令。

在一些复杂业务中,如果不知道某一个方法的调用链路,可以用这个命令查看调用链路。或者 不同的业务场景调用链路不一样时,也可以使用这个命令确定某个业务数据的调用链路。

命令如下:

stack  com.zero.secret.service.AlbumService getAlbum

效果如下:

monitor (监控某个方法在一段时间内容的执行次数、成功的次数,失败的次数,平均耗时)

该命令的官方文档 monitor

命令如下:

monitor -c 10  com.zero.secret.web.controller.AlbumController home

上面是10s 统计一次。

结果如下:

dashboard(查看JVM 资源占用及垃圾回收情况)

thread(可以查看CPU资源占用靠前的几个线程详情,阻塞线程)

详情参考 thread 命令 这个命令可以查看当前CPU资源占用比较靠前的几个线程详情,能直观的看到比较耗资源的几个线程在干什么,方便排查问题。不用dump出堆栈,直接可以看,使用比较轻量级。

查看CPU占用靠前的几个线程

命令如下:

thread -n 3

结果如下:

找当前阻塞其它线程的线程

这个命令目前只能支持找出找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持。实用性不够。 命令如下:

thread -b

结果看一下官方给的例子

logger(可以动态的修改 logger的级别,可以指定 package 的级别)

这个命令也比较实用。

sc sm (sc 查看jvm加载的class,sm 查看jvm加载的类的方法)

官方命令 sc sm sc 查看class类,sm 查找class类的方法列表

[arthas@15658]$ sc *Albumcom.zero.secret.dal.dto.AlbumAffect(row-cnt:1) cost in 30 ms.[arthas@15658]$ sm com.zero.secret.dal.dto.Albumcom.zero.secret.dal.dto.Album ()Vcom.zero.secret.dal.dto.Album getTag()Ljava/lang/String;com.zero.secret.dal.dto.Album getDesc()Ljava/lang/String;com.zero.secret.dal.dto.Album getStatus()Ljava/lang/Integer;com.zero.secret.dal.dto.Album setStatus(Ljava/lang/Integer;)Vcom.zero.secret.dal.dto.Album getImgs()Ljava/util/List;com.zero.secret.dal.dto.Album getGirlId()Ljava/lang/Long;com.zero.secret.dal.dto.Album setDesc(Ljava/lang/String;)Vcom.zero.secret.dal.dto.Album setTitle(Ljava/lang/String;)Vcom.zero.secret.dal.dto.Album setCreateTime(Ljava/util/Date;)Vcom.zero.secret.dal.dto.Album setUpdateTime(Ljava/util/Date;)Vcom.zero.secret.dal.dto.Album setGirlId(Ljava/lang/Long;)V

heapdump 打印堆栈

官方命令 heapdump 这个命令很简单,打印堆栈。

[arthas@15658]$ heapdump /data/dump.hprofDumping heap to /data/dump.hprof...Heap dump file created

getstatic 获取类的静态成员变量的值

官方命令文档:getstatic

获取类内部静态成员变量的值。

[arthas@15658]$ getstatic com.zero.secret.web.controller.AlbumController  PAGE_SIZEfield: PAGE_SIZE@Integer[25]Affect(row-cnt:1) cost in 8 ms.

jad、mc、redefine (反编译、编译、热部署)

以上命令的官方文档详见:jad mc redefine

反编译AlbumController

[arthas@15658]$ jad com.zero.secret.web.controller.AlbumControllerClassLoader:+-org.springframework.boot.loader.LaunchedURLClassLoader@5d099f62  +-sun.misc.Launcher$AppClassLoader@55f96302    +-sun.misc.Launcher$ExtClassLoader@5dbd8ca1Location:file:/data/secret/web/secret-web.jar!/BOOT-INF/classes!/

上面信息很重要,记住当前类的classloader编号 5d099f62。接下来把反编译的源码输出到我们方便编辑的目录,如下:

jad --source-only com.zero.secret.web.controller.AlbumController > /data/artas/AlbumController.java

编辑 AlbumController.java 源文件,加一行日志:

将编辑好的源文件AlbumController.java 编译到目标位置,mc 指定需要加载器,否则容易出现很多依赖找不到的情况。这里是指定原来的类加载器来编译,且默认的class文件是在原来的class文件位置。后面只需要热加载即可。

[arthas@15658]$ mc -c 5d099f62  /data/artas/AlbumController.javaMemory compiler output:/data/secret/web/com/zero/secret/web/controller/AlbumController.classAffect(row-cnt:1) cost in 5279 ms.

接下来热加载,同样,指定原来的类加载器。

[arthas@15658]$ redefine -c 5d099f62  /data/secret/web/com/zero/secret/web/controller/AlbumController.classredefine success, size: 1

最后看一下执行的结果。

这样,不用重新发布应用,就可以测试某些功能是否能解决问题。

关于Java线上诊断工具Arthas的使用方法就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

0