【Arthas工具】使用Trace命令分析Java JVM方法调用链路及耗时

软件环境

问题背景

生产方法调用存在耗时长,通过日志无法定位耗时长的行(日志打印位置也不合理)

实操

案例一:Kafka消费客户端

说明:存在一个业务多个节点串行异步处理

Step.1: 启动arthas

Step.2: 选择应用(java进程id)

Step.3: 方法执行链路追踪

bash 复制代码
trace com.***.crm.channel.dataSyn.service.impl.MssCloudInfoSyncServiceImpl pullDataFinish  -n 5 --skipJDKMethod false

说明:限制追踪次数

-n 参数指定限制追踪次数

Step.4: 停止对方法的追踪

bash 复制代码
# 
stop com.***.crm.channel.dataSyn.service.impl.MssCloudInfoSyncServiceImpl pullDataFinish  -n 5 --skipJDKMethod false

案例二:SAAS健康度定时任务

Step.1: 启动arthas

Step.2: 选择应用(java进程id)

这里选择的是第二个应用:smet-rpc-service

bash 复制代码
[tomcat@GZCRM-PM153121 arthas-4.1.3]$ ls
arthas-agent.jar  arthas-client.jar  arthas.properties  as.bat          as.sh           install-local.sh  logback.xml
arthas-boot.jar   arthas-core.jar    arthas-spy.jar     as-service.bat  async-profiler  lib               math-game.jar
[tomcat@GZCRM-PM153121 arthas-4.1.3]$ ./as.sh
Arthas script version: 4.1.3
[INFO] JAVA_HOME: /usr/lib/jvm/jdk-17-oracle-x64
Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 2031341 ops-portal.jar
  [2]: 715630 smet-rpc-service-1.0-SNAPSHOT.jar
  [3]: 88806 kafka-map.jar
  [4]: 715629 smet-rpc-service-1.0-SNAPSHOT.jar
  [5]: 103069 org.apache.zookeeper.server.quorum.QuorumPeerMain
  [6]: 103581 play.core.server.ProdServerStart
2
Arthas home: /app/arthas/arthas-4.1.3
Calculating attach execution time...
Attaching to 715630 using version /app/arthas/arthas-4.1.3...

real    0m2.328s
user    0m0.500s
sys     0m0.067s
Attach success.
telnet connecting to arthas server... current timestamp is 1766021265
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.                           
 /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'                          
|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.                          
|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |                         
`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'                          

wiki         https://arthas.aliyun.com/doc                                      
tutorials    https://arthas.aliyun.com/doc/arthas-tutorials.html                
version      4.1.3                                                              
main_class   smet-rpc-service-1.0-SNAPSHOT.jar                                  
pid          715630                                                             
start_time   2025-12-12 16:00:12.425                                            
current_time 2025-12-18 09:27:44.599                                            

[arthas@715630]$ 

Step.3: 方法执行链路追踪

bash 复制代码
[arthas@715630]$ trace com.***.nctc.smet.job.promesaas.ClickHouseStatus3Count3Job  execute
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 553 ms, listenerId: 9
`---ts=2025-12-18 09:46:00.245;thread_name=ClickHouseStatus3Count3Job2_Worker-1;id=258;is_daemon=false;priority=5;TCCL=jdk.internal.loader.ClassLoaders$AppClassLoader@7ad041f3
    `---[44354.950448ms] com.
***.nctc.smet.job.promesaas.ClickHouseStatus3Count3Job:execute() [throws Exception]
        +---[0.00% 0.012141ms ] org.apache.shardingsphere.elasticjob.api.ShardingContext:getJobName() #100
        +---[0.00% 0.008851ms ] org.apache.shardingsphere.elasticjob.api.ShardingContext:getShardingItem() #102
        +---[0.00% 0.007734ms ] org.apache.shardingsphere.elasticjob.api.ShardingContext:getShardingParameter() #110
        +---[0.00% 0.007913ms ] org.apache.shardingsphere.elasticjob.api.ShardingContext:getShardingTotalCount() #118
        +---[0.00% 0.113764ms ] org.slf4j.Logger:info() #120
        +---[0.00% 0.027815ms ] com.***.nctc.smet.util.TimeUtils:calcWholeMinute() #140
        +---[0.00% 0.347037ms ] com.***.nctc.sml.service.redis.DistributedLockChecker:lock() #161
        +---[0.00% 0.063908ms ] org.slf4j.Logger:info() #164
        +---[8.70% 3857.747108ms ] com.***.nctc.sml.service.prome.ClickHouseClientAppStatusService:insertAppStatusRS2() #165
        +---[0.00% 0.058561ms ] org.slf4j.Logger:info() #166
        +---[0.00% 0.06223ms ] org.slf4j.Logger:info() #167
        +---[0.59% 261.989537ms ] com.***.nctc.sml.service.prome.ClickHouseClientAppCountService:insertAppCountRS2() #169
        +---[0.00% 0.053399ms ] org.slf4j.Logger:info() #170
        +---[0.00% 0.051497ms ] org.slf4j.Logger:info() #173
        +---[14.99% 6649.567466ms ] com.***.nctc.sml.service.prome.ClickHouseClientPodStatusService:insertPodStatusRS2() #174
        +---[0.00% 0.082961ms ] org.slf4j.Logger:info() #175
        +---[0.00% 0.058916ms ] org.slf4j.Logger:info() #176
        +---[1.26% 558.048584ms ] com.***.nctc.sml.service.prome.ClickHouseClientPodCountService:insertPodCountRS2() #177
        +---[0.00% 0.094819ms ] org.slf4j.Logger:info() #178
        +---[0.00% 0.062951ms ] org.slf4j.Logger:info() #192
        +---[0.00% 0.415303ms ] com.***.nctc.sml.service.redis.DistributedLockChecker:unlock() #194
        +---[2.26% 1000.76531ms ] com.***.nctc.sml.service.redis.DistributedLockChecker:obtainlock() #196
        +---[2.26% 1000.562038ms ] com.
***.nctc.sml.service.redis.DistributedLockChecker:obtainlock() #197
        +---[2.26% 1000.528768ms ] com.
***.nctc.sml.service.redis.DistributedLockChecker:obtainlock() #203
        +---[0.00% 0.096488ms ] org.slf4j.Logger:info() #205
        +---[67.69% 30021.808559ms ] com.
***.nctc.sml.service.topmetric.PodHealthService:insertPodHealth() #206 [throws Exception]
        +---[0.00% 0.105759ms ] org.slf4j.Logger:error() #270
        +---[0.00% 0.42062ms ] com.
***.nctc.sml.service.redis.DistributedLockChecker:unlock() #286
        `---throw:java.lang.RuntimeException #272 [org.springframework.dao.DataAccessResourceFailureException: StatementCallback; SQL [SELECT sas.process_available AS process_available,       smp.saas_health  AS pod_saas_health,       smp********  AND sps.cluster  ='02']; Read timed out; nested exception is java.sql.SQLException: Read timed out]

说明工具默认会将耗时最长的标红

Step.4: 停止对方法的追踪

bash 复制代码
stop com.***.nctc.smet.job.promesaas.ClickHouseStatus3Count3Job execute

附件一:Arthas简介

Arthas 是一款由阿里巴巴开源的 Java 诊断工具,旨在帮助开发者高效排查线上应用问题。它通过无侵入的方式附着到运行中的 JVM 进程,提供实时监控和动态诊断能力,无需修改代码或重启应用即可完成问题定位。‌

该工具的核心功能包括:

  • 全局视角监控‌:实时查看应用的负载、内存、GC、线程等状态信息,快速识别性能瓶颈。‌
  • 方法级诊断 ‌:支持观察方法调用的入参、出参、异常和执行耗时,通过命令如 watchtrace 等深入分析业务逻辑。‌
  • JVM 与类分析‌:提供类加载详情、线程堆栈、内存使用情况等,帮助定位类冲突、内存泄漏等问题。‌
  • 热更新与调试‌:允许动态修改类字节码,实现热部署,并支持远程调试,减少线上服务中断时间。‌

Arthas 基于 Java Instrumentation 和 Attach 机制实现字节码增强,兼容 JDK 6 及以上版本,可在 Linux、Mac、Windows 等多平台使用。其命令行界面支持 Tab 补全和丰富的插件扩展,适用于 Spring Boot、Dubbo 等主流框架。‌

附件二:常用命令举例

  1. 查看JVM信息

    bash 复制代码
    help

    查看Arthas支持的命令列表。

  2. 查看当前线程信息

    bash 复制代码
    thread

    查看当前所有活跃的线程及其状态。

  3. 查看某个类的所有方法及其执行时间

    bash 复制代码
    watch com.example.MyClass methods -x 2

    监控com.example.MyClass类中所有方法的执行时间,输出前两次执行的结果。

  4. 实时修改类的方法

    bash 复制代码
    redefine /path/to/new/MyClass.class

    替换MyClass的字节码,实现类的动态修改。

  5. 查看堆内存使用情况

    bash 复制代码
    heapdump /path/to/heapdump.hprof

    生成堆内存的转储文件,便于后续使用其他工具(如MAT)进行分析。

  6. 跟踪某个方法的调用

    bash 复制代码
    trace com.example.MyClass methodName

    跟踪com.example.MyClassmethodName方法的每次调用。

  7. 查看类的加载情况

    bash 复制代码
    smap com.example.MyClass

    查看com.example.MyClass类的加载信息,包括加载时机、来源等。

注意事项

  • 使用Arthas时,确保你有足够的权限来操作目标Java进程。
  • 在生产环境中使用前,建议先在测试环境中验证命令的效果和安全性。
  • 动态修改类和重新定义方法可能会带来不可预见的副作用,谨慎使用。
  • Arthas的安装和启动通常需要依赖Java环境,确保目标机器上已安装Java并配置了相应的环境变量。

通过上述命令和功能,Arthas为Java开发者提供了一套强大的实时诊断和修复工具,极大地提升了开发和运维的效率。

附件三:参考网址

https://arthas.aliyun.com/3.x/

https://arthas.aliyun.com/ -- 4.X

https://gitee.com/arthas/arthas

https://github.com/alibaba/arthas/releases

相关推荐
7ioik2 小时前
JVM 调优工具深度指南:从监控到诊断的全流程实战
jvm
Han.miracle2 小时前
Spring MVC 请求参数处理全解析
java·请求
winfield8212 小时前
Java 的静态代理和动态代理
java·代理模式
222you2 小时前
Java的Stream流
java·开发语言
kevinzeng2 小时前
Redis的IO多路复用
java·redis
2501_916766542 小时前
【SpringMVC】异常处理和拦截器
java·spring
不惑_2 小时前
在 Docker 中运行 Java JAR 包实战教程
java·docker·jar
一勺菠萝丶2 小时前
解决Java中IP地址访问HTTPS接口的SSL证书验证问题
java·tcp/ip·https
墨着染霜华2 小时前
IntelliJ IDEA 设置导出与导入完整指南(备份 / 迁移 / 团队共享)
java·ide·intellij-idea