Arthas是Alibaba开源的一款Java诊断工具,其提供了丰富的命令。这里介绍其中的trace、monitor、watch命令
trace
可以跟踪指定方法调用的耗时,为便于演示,提供下述测试代码
1 | package com.aaron.Arthas; |
基本实践
该命令用法如下所示
1 | # 跟踪指定类的指定方法中的耗时 |
不难看出,trace命令只会跟踪、统计被匹配到的函数里的子调用,并不会向下trace多层
统计JDK方法调用
默认情况下,trace结果中不会对JDK方法调用进行耗时统计。故如果期望含有对JDK方法调用的耗时统计,需显式使用 —skipJDKMethod false 选项
1 | # 跟踪com.aaron.Arthas.TestTrace类中addUserController方法的耗时,同时包含对JDK方法调用的统计 |
支持正则匹配
trace命令提供了-E选项,可以通过正则表达式来匹配多个类、方法。在一定程度上可以达到实现多层trace对效果
1 | # 跟踪com.aaron.Arthas.TestTrace类中addUserController、serviceA、serviceB方法的耗时 |
1 | # 跟踪com.aaron.Arthas.TestTrace类中方法名以add2开头的方法耗时 |
动态trace
我们在终端1对addUserController进行trace,从下述输出中不难看出,其listenerId为7
假设我们现在期望对serviceA方法中的调用耗时进行分析,则可以在终端2中,先使用telnet连接Arthas,然后使用trace命令跟踪serviceA方法。与此同时在trace命令中使用—listenerId选项指定在终端1中看到的listenerId值即可
1 | # 终端2的命令 |
现在我们回到终端1进行观察,即会发现输出结果中包含了对servcieA方法的调用耗时分析结果。事实上通过这种方式,我们可以不断按需深入trace
monitor
该命令可以对方法进行监控,监控指标包括调用次数、成功次数、失败次数、平均RT(平均响应时间)、失败率。其中这里失败的判定标准为方法执行抛出异常。这里提供如下的测试代码
1 | package com.aaron.Arthas; |
使用方式很简单,指定类名、方法名即可。同时-c选项表示统计周期,单位为秒。默认为120秒
1 | monitor -c 5 com.aaron.Arthas.TestMonitor calc |
还可以通过-b选项搭配条件表达式,实现对特定场景下的方法调用进行统计
1 | # 对TestMonitor的calc方法,当第一个参数值为false时进行监控 |
watch
便于观察指定方法的调用情况。具体地,可以观察到:方法入参、方法返回值、方法抛出异常。故watch命令定义了4个观察事件点。并提供了对应的方法选项
-b:在方法被调用前进行观察。当使用该选项时,由于观察事件点是在方法被调用之前,此时方法的返回值或异常均无法观察到。即只能观察到方法的入参
-e:在方法调用抛出异常时,进行观察。
-s:在方法调用正常返回时,进行观察。
-f:在方法调用结束后进行观察。显然该选项即会观察到方法抛出异常的情形,也会观察到方法正常返回的情形。除了该选项默认打开外,上述3个选项均默认关闭
为了便于演示,提供下述测试代码
1 | package com.aaron.Arthas; |
观察方法调用时的入参
我们通过 -b选项 观察TestWatch中calc方法被调用时的方法入参,同时指定观察表达式 {params,target,returnObj} ,其中params、target、returnObj分别表示入参、调用类的实例、返回值。 -x选项 则用于指定对输出结果中属性遍历的深度,默认为1,最大为4
1 | # 通过-b选项观察TestWatch中calc方法被调用时的方法入参 |
下述红框表示观察表达式的第1个元素params,即方法的入参;下述蓝框表示观察表达式的第2个元素target,即调用方法的实例;下述蓝框表示观察表达式的第3个元素returnObj,即方法的出参。此外输出结果的location值为AtEnter,表示观察事件的位置在函数入口
观察方法调用时的返回值
1 | # 通过-s选项观察TestWatch中calc方法被调用时的方法入参、返回值 |
此外输出结果的location值为AtExit,表示观察事件的位置在函数正常返回
观察方法调用时抛出的异常
在观察表达式中,可使用throwExp表示异常信息
1 | # 通过-e选项观察TestWatch中calc方法被调用时的方法入参、抛出的异常 |
此外输出结果的location值为AtExceptionExit,表示观察事件的位置在函数抛出异常
观察方法调用的结果
1 | # 通过-f选项观察TestWatch中calc方法被调用后的结果(包含正常返回、抛出异常两种情形) |
使用条件表达式进行过滤
我们还可以通过条件表达式实现仅对我们期望的场景进行观察,以免输出结果太多造成干扰
1 | # 对TestWatch中calc方法进行观察, 同时要求 方法第一个参数的值大于2 且 方法第一个参数值为偶数 时才进行观察 |