HOOOS

Arthas实战:如何非侵入式监控方法实时调用与排查性能瓶颈?

0 5 码农老王 ArthasJava诊断性能监控
Apple

线上环境无法进行传统意义上的断点调试,这无疑是许多Java开发者在排查问题时的一大痛点。当遇到某个方法执行缓慢,或者想了解其调用频率、成功率等实时指标时,如果不能侵入式地修改代码、发布重启,我们该怎么办?

Arthas,作为阿里巴巴开源的Java诊断工具,正是为解决这类问题而生。它以非侵入式的方式,在不重启JVM的情况下,提供了强大的运行时诊断能力。下面我们就来详细探讨,如何利用Arthas查看某个方法的实时调用情况,并分析其性能瓶颈。

Arthas简介

Arthas是一款Java应用线上诊断工具,当应用部署在生产环境出现问题时,Arthas可以帮助我们快速定位并解决问题。它支持对运行中的JVM进行热插拔,提供诸如查看JVM信息、线程信息、类加载信息、方法调用链路、性能指标等功能,是线上问题排查的利器。

第一步:连接到目标JVM进程

在使用Arthas之前,首先需要将它attach到你的Java应用进程上。

  1. 下载Arthas:

    curl -O https://arthas.aliyun.com/arthas-boot.jar
    
  2. 启动Arthas:

    java -jar arthas-boot.jar
    

    执行后,Arthas会列出当前机器上运行的Java进程,让你选择要attach的进程ID。输入对应的PID,回车即可连接。

    * [1]: 12345 your-application.jar
    * [2]: 67890 another-application.jar
    ...
    Please choose a Java process to attach, input index[1,2]:
    

    选择你的应用进程ID后,你就进入了Arthas控制台。

第二步:监控方法的实时调用情况

针对“查看某个方法的实时调用情况”和“分析性能瓶颈”的需求,Arthas提供了monitortrace等核心命令。

1. 使用 monitor 命令监控方法统计信息

monitor 命令用于监控指定方法的执行统计信息,包括调用次数、成功失败次数、平均响应时间(RT)、QPS(每秒查询数)等。这对于快速了解一个方法的整体健康状况和性能表现非常有用。

命令格式:
monitor -c [统计周期] [类全限定名] [方法名]

示例: 假设我们有一个com.example.service.UserService类,其中有一个getUserById方法,我们想每隔5秒监控一次它的调用情况。

monitor -c 5 com.example.service.UserService getUserById

输出示例解析:

Press Ctrl+C to abort.
Time          Total  Success  Fail  RT(ms)  QPS  Failed(%)
--------------------------------------------------------------------------
2023-10-27 10:00:05  100    95     5     12.5   20   5.00
2023-10-27 10:00:10  120    118    2     10.2   24   1.67
...
  • Time: 统计时间点。
  • Total: 总调用次数。
  • Success: 成功次数。
  • Fail: 失败次数。
  • RT(ms): 平均响应时间(毫秒)。
  • QPS: 每秒查询数。
  • Failed(%): 失败率。

通过monitor,你可以直观地看到方法的调用频率是否异常、响应时间是否过长,以及是否有大量失败,从而快速定位到可能存在问题的服务或方法。

2. 使用 trace 命令追踪方法内部调用路径及耗时

monitor发现某个方法的RT过高时,我们可能需要进一步了解这个方法内部是哪一步耗时较长,这时trace命令就派上用场了。trace可以追踪方法执行的整个路径,并记录每个子方法调用的耗时。

命令格式:
trace [类全限定名] [方法名] [条件表达式] -n [调用次数]

示例: 继续上面的例子,我们怀疑getUserById内部有耗时操作,想追踪它。

trace com.example.service.UserService getUserById

或者,如果只想追踪前5次调用:

trace com.example.service.UserService getUserById -n 5

如果方法参数或返回值较大,或者需要过滤特定调用,还可以结合watch命令进行更详细的观察,或者使用条件表达式。

输出示例解析:

`---ts=2023-10-27 10:05:01; [cost=15.341ms] thread=main`
    `---[com.example.service.UserService:getUserById()]`
        `---[com.example.dao.UserDAO:selectById() cost=10.210ms]`
        `---[com.example.cache.UserCache:put() cost=2.150ms]`
        `---[com.example.util.DataConverter:convert() cost=0.500ms]`
  • cost: 表示当前方法或子方法从开始到结束的执行总耗时。
  • 输出会以树形结构展示方法的调用链路,每个子方法前会显示其自身的耗时。
  • 通过观察cost值,可以清晰地看到getUserById方法中,selectById()耗时最长,这可能就是性能瓶颈所在。

过滤条件 (-E 或 SpEL表达式):
当你只想追踪满足特定条件的方法调用时,可以使用条件表达式。例如,只追踪用户ID为100的调用:

trace com.example.service.UserService getUserById "params[0]==100"

这里params[0]表示第一个方法参数。

第三步:停止Arthas命令

当完成诊断后,可以通过Ctrl+C停止当前正在执行的命令(如monitortrace)。
如果想退出Arthas控制台,可以使用quitexit命令。

总结

Arthas提供了一种强大的非侵入式方式来诊断线上Java应用。

  • monitor 让你能从宏观层面了解方法的调用统计信息,快速发现异常的QPS、RT或失败率。
  • trace 则深入到微观层面,帮你剖析方法内部的调用链和各环节的耗时,精确锁定性能瓶颈。

结合这两个命令,你可以高效地在不影响线上服务的前提下,进行实时的性能分析和问题排查。掌握Arthas,无疑会大大提升你在生产环境下的问题解决能力。

点评评价

captcha
健康