Arthas在线上debug中解决的10个问题

 

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

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

使用sc命令可以查看指定类的详细信息,包括从哪个jar包加载。

 

sc *.OfficeListService -d

 Arthas在线上debug中解决的10个问题

 

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

如果需要确认当前运行的代码,可以通过jad命令,反编译出代码。

 

jad *.OfficeListService queryOfficeUser

 

 Arthas在线上debug中解决的10个问题

 

 

 

 

 

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

arthas有一系列命令可以对线上代码进行监测。启动监测后,每当方法被调用就会输出监测的相关数据。

 

watch命令:对指定方法进行数据观测,包括入参、返回值和抛出异常。

 

watch *.FormController queryApplyDataDetail -f {params,returnObj} -x2

 Arthas在线上debug中解决的10个问题

 

 

 

monitor命令:统计指定方法的调用情况,调用次数、成功次数、平均执行时间等

 

monitor -c 5 *.DashboardMetaController queryList

Arthas在线上debug中解决的10个问题

 

 

stack命令:输出指定方法被调用的路径。

 

stack *.FormDataService queryDataDetail

 

 Arthas在线上debug中解决的10个问题

 

 

4. debug时,想在代码中添加日志,但为一行日志代码重新发布太麻烦了。

arthas支持代码热更新,不需要项目重新发布,只修改需要的代码,编译后就可以替换线上正在运行的类。

 

比如现在线上运行的getVersion接口,现在要修改成返回arthas_test_version”。

 

jad命令反编译出接口所在类的代码,输出成文件。

 

jad --source-only com.****.system.rest.system.sys.SysConfigController > ~/arthas_test/SysConfigController.java

 

修改输出的代码。

 Arthas在线上debug中解决的10个问题

 

 

 

sc命令+grep命令,找出类的classLoader的哈希值

 

 

 

sc -d com.****.system.rest.system.sys.SysConfigController | grep classLoaderHash

 Arthas在线上debug中解决的10个问题

 

 

mc命令将修改后的代码编译成class文件。-c后的参数就是找出的classLoader的哈希值。

 

mc -c 7c81d32b ~/arthas_test/SysConfigController.java -d ~/arthas_test

 

 Arthas在线上debug中解决的10个问题

 

 

 

最后,redefine命令加载新的class文件。

 

redefine ~/arthas_test/com/****/system/rest/system/sys/SysConfigController.class

 

 Arthas在线上debug中解决的10个问题

 

 

 

再次调用接口,可以看出运行的已经是修改后的代码。

 Arthas在线上debug中解决的10个问题

 

 

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

tt命令可以在后台观测并保存指定方法调用时的参数、返回值、异常等信息,并可以用保存的参数再次调用方法。

 

另外,设置ognl表达式可以让命令在满足条件时才保存记录。例如,出现异常时才保存。

 

tt -t *.FormController queryById "returnObj.contains(‘\"status\":500‘)" >> tt_logs.txt  &

 

该命令观测FormControllerqueryById方法,并且只有在返回值字符串中包含status:500时才记录。另外,>>符号将调用记录重定向到tt_logs.txt文件中,&”让命令在后台执行,关闭终端也能一直运行。

 

接下来进行一次出错的调用,可以看出tt记录了这次调用。

 

 Arthas在线上debug中解决的10个问题

 

 

 

根据编号,查看调用的详细信息。

 

tt -i 1006

 Arthas在线上debug中解决的10个问题

 

 

 

另外,可以重放指定编号的调用,显示第二次调用的结果。

 

tt -i 1006 -p

 Arthas在线上debug中解决的10个问题

 

 

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

dashboard命令会显示当前系统的实时数据面板包括线程、内存、GC、运行时等信息

Arthas在线上debug中解决的10个问题

 

 

 

 

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

除了dashboard命令的数据面板外,还有thread命令可以显示当前线程信息。

 Arthas在线上debug中解决的10个问题

 

 

 

可以根据id查看具体线程的堆栈。

thread 187

 

 Arthas在线上debug中解决的10个问题

 

 

 

8. 怎么快速定位应用的热点,生成火焰图

profiler命令可以在一段时间内对数据采样,生成火焰图。

 

profiler start --duration 300

 

该命令对cpu进行300秒的采样。也可以指定对其他数据进行采样。

 

采样后生成svghtml格式的火焰图。

 Arthas在线上debug中解决的10个问题

 

 

 

9. 怎样直接从JVM内查找某个类的实例

vmtool命令可以查询指定类的内存对象。

 

vmtool --action getInstances --className java.lang.String -limit 30

 

该命令查找内存中的String对象,限定前30个。

 Arthas在线上debug中解决的10个问题

 

 

 

10. 进行性能调优时需要在代码里添加大量计时器代码,还要重新部署,太麻烦?

trace命令能记录指定方法的调用路径,并统计方法向下一层调用的耗时。

 

trace *DashboardMetaController queryList

 

 Arthas在线上debug中解决的10个问题

 

 

 

这条监测记录中可以看出queryList方法调用了CommonService:queryPage方法,耗时18ms,占比最大,因此可以trace这个方法,向下深入,最终找出性能瓶颈。

Arthas在线上debug中解决的10个问题

上一篇:超简单的分表脚本-将汇总sheet按条件拆分成多个sheet


下一篇:gin框架 简介