在Java开发中,生产环境的问题排查往往是最棘手的一环。日志不全、无法远程调试、问题难以复现......这些痛点相信大家都深有体会。
今天,我们来聊聊一款强大的Java诊断工具------Arthas(阿尔萨斯)。它由阿里巴巴开源,能够让你在不重启应用、不修改代码的情况下,实时监控、诊断和定位Java应用的问题,堪称生产环境问题排查的"瑞士军刀"。
本文将带你从零开始,快速掌握Arthas的安装、核心功能及实战技巧。
一、快速开始:下载与启动
1. 下载启动包
使用curl命令即可快速下载Arthas的启动包:
curl -O https://arthas.aliyun.com/arthas-boot.jar
注意 :参数
-O(大写字母O)表示保持原文件名下载,即保存为arthas-boot.jar。
2. 启动与连接
Arthas启动后,需要连接到一个正在运行的Java进程。
-
简单启动(交互式选择进程) :
直接在终端执行以下命令,Arthas会列出所有Java进程,并提示你选择要连接的进程编号。
java -jar arthas-boot.jar -
指定PID启动 :
使用
jps或ps命令获取目标Java进程的PID,然后直接连接。java -jar arthas-boot.jar <PID> # 例如:java -jar arthas-boot.jar 12345 -
K8s Pod内使用 :
在Pod内只有一个Java应用容器时,该进程的默认PID为1。可以直接执行:
java -jar arthas-boot.jar 1
二、核心功能与应用场景
Arthas提供了丰富的命令,下面介绍几个最常用、最核心的功能。
1. 全局数据看板之dashboard
功能:实时监控系统的核心指标,包括线程状态、内存使用、GC情况和系统负载。
场景:快速感知系统健康度,初步定位CPU占用过高、内存泄漏或频繁GC等全局性问题。
示例输出(部分):
| 线程ID | 线程名称 | 状态 | CPU% |
|---|---|---|---|
| 18 | AsyncAppender-Worker-Thread-5 | WAITING | 11.56 |
| 16258 | pool-1478-thread-1 | RUNNABLE | 6.43 |
| ... | ... | ... | ... |
| 内存区域 | 已使用 | 总量 | 使用率 |
| heap | 1152M | 2338M | 42.53% |
| ps_old_gen | 1111M | 1681M | 54.68% |
通过dashboard,你可以一目了然地看到哪个线程最"活跃",哪个内存区域压力最大。
2. 方法调用监控之monitor
功能:监控指定方法的调用次数、平均响应时间、失败率等关键指标。
场景:用于监控核心接口的QPS、RT和成功率,评估系统性能。
性能提示 :monitor命令通过字节码增强实现,有一定性能开销。生产环境建议缩短监控周期或在低峰期使用。
常用命令示例:
# 1. 监控指定方法,默认统计周期为120秒
monitor com.example.service.FlightService searchFlight
# 2. 指定统计周期为10秒
monitor -c 10 com.example.service.FlightService searchFlight
# 3. 监控并限制每次刷新最多显示5条数据
monitor -c 10 -n 5 com.example.service.FlightService searchFlight
# 4. 监控类下的所有方法(使用通配符)
monitor com.example.service.FlightService *
# 5. 监控某个包及其子包下所有类中名称匹配的方法
monitor com.example.service..*FlightService searchFlight
3. 方法执行数据观测之watch
功能:观测方法调用的入参、返回值、异常和耗时,是定位问题的"放大镜"。
场景:当怀疑方法入参异常、返回值错误或抛出特定异常时,用于快速捕获现场数据。
实战案例:定位慢调用与异常
# 1. 监控控制器层接口,过滤耗时大于1秒的慢调用
watch com.example.controller.FlightController searchFlight "{params, #cost}" '#cost>1000' -x 2
# 2. 若发现慢调用,进一步下钻到内部HTTP客户端调用,过滤耗时大于800毫秒的调用
watch com.example.client.IbeClient callIbe "{params, #cost}" '#cost>800' -x 2
# 3. 同时监控同一方法是否抛出异常
watch com.example.client.IbeClient callIbe "{params, throwExp}" -e -x 2
常用OGNL观察表达式模板:
| 观察目标 | OGNL表达式 |
|---|---|
| 所有入参 | {params} |
| 第一个入参 | {params[0]} |
| 入参的特定属性 | {params[0].departureCity} |
| 返回值对象 | {returnObj} |
| 返回值的特定属性 | {returnObj.statusCode} |
| 异常对象 | {throwExp} |
| 异常信息 | {throwExp.message} |
| 入参 + 耗时 | {params, #cost} |
| 完整调用上下文 | {params, returnObj, #cost} |
4. 方法调用链路追踪之trace
功能:定位方法内部子调用的性能瓶颈,分析各步骤耗时占比。
场景 :当一个接口响应很慢时,使用trace可以逐层下钻,找到最耗时的那个子方法。
实战演练:逐层下钻定位瓶颈
-
第一层Trace:发现瓶颈在下一层。
trace com.example.service.impl.FlightServiceImpl searchFlight # 输出:99% 耗时在 executeWithoutTransaction 方法 -
第二层Trace:继续下钻。
trace com.example.core.ServiceTemplateImpl executeWithoutTransaction # 输出:99% 耗时在 executeAction 方法 -
关键层Trace:定位到具体耗时操作。
trace com.example.task.SearchFlightTask convertShopResult # 输出:99% 耗时在 invokeAll (可能为并行处理或远程调用)
定位网络I/O阻塞(实战技巧) :
当应用表现为HTTP请求卡住/接口请求504/线程池队列激增时,可检查线程状态:
# 查找正在进行socket读操作的线程(通常意味着在等待网络响应)
thread -n 200 | grep socketRead0
# socketRead0 对应 java.net.SocketInputStream.socketRead0(Native Method)
重要限制 :
trace依赖于当前线程上下文。当遇到异步调用(如invokeAll、submit到线程池)时,跟踪链路会中断。此时需结合thread命令进行全局分析。
三、实用辅助与进阶功能
1. 类与代码探查
-
搜索已加载的类 (
sc):sc com.example.bean.* -
反编译源码 (
jad) :在线查看字节码对应的Java源码,用于验证线上代码版本或理解逻辑。
jad com.example.service.impl.UserServiceImpl
2. 性能热点精准定位
-
系统级CPU热点(Linux命令):
top -n 5快速找出系统内最耗CPU的进程,辅助判断是否为Java进程导致。
-
JVM线程级CPU排行(Arthas命令):
thread -n 10 -i 1000统计过去1秒内,JVM中CPU占用率最高的前10个线程。适用于CPU突然飙高(如死循环)的场景。
-
查看类方法列表(Trace前置步骤):
sm com.example.service.FlightService在
trace或watch前使用,确认方法名和签名是否正确,避免因方法名错误导致监控失败。
四、最佳实践与注意事项
- 环境隔离:生产环境使用前,务必在测试环境充分验证命令效果,避免不当操作影响线上服务。
- 最小化监控 :使用
-c参数控制监控周期,使用-n参数限制输出条数,降低性能影响。 - 组合使用 :推荐的问题排查流程:
dashboard-> 宏观感知thread/top-> 定位热点线程trace/watch-> 下钻分析具体方法jad/sc-> 探查代码细节
- 及时退出 :使用完成后,通过
stop命令退出Arthas客户端。
最后一句
Arthas的强大之处在于,它几乎可以解决你在生产环境中遇到的所有Java问题,从CPU飙升、内存泄漏到慢调用、死锁。掌握它,将极大提升你的线上问题排查效率。
希望这篇文章能帮助你快速上手Arthas。如果你有任何问题或更好的使用技巧,欢迎在评论区留言交流!