Arthas线上诊断实战指南
AI摘要
Arthas是阿里巴巴开源的Java诊断工具,能够在不重启应用的情况下实时查看和修改JVM运行状态。它适用于排查线上Java性能问题、内存泄漏、CPU飙高等问题。本文详细介绍了Arthas的安装方式、常用诊断场景、高级用法以及生产环境最佳实践,帮助开发者提升问题排查效率。
线上 Java 应用出问题了?别急着重启
Arthas 是什么
Arthas 是阿里开源的 Java 诊断工具。线上应用突然 CPU 飙高、接口变慢、内存泄漏,你不用重启应用就能实时查看 JVM 状态,甚至热更新代码。我在生产环境用它救过好几次火。
什么时候该用它
遇到这些情况,Arthas 能帮上忙:
- CPU 突然飙到 100%,不知道哪个方法在疯狂运行
- 接口响应从 100ms 突然变成 5 秒,调用链路不清楚
- 内存一直涨,怀疑有泄漏但不确定
- 类加载冲突,想看看实际加载的是哪个版本
- 线上紧急 bug,等不及走发布流程
- 想看看 JVM 参数、线程状态、GC 情况
安装
最简单的方式
# 下载
curl -O https://arthas.aliyun.com/arthas-boot.jar
# 启动
java -jar arthas-boot.jar启动后会列出所有 Java 进程,输入序号就能 attach 上去。
完整安装
curl -O https://arthas.aliyun.com/arthas-packaging-latest.zip
unzip arthas-packaging-latest.zip
./as.sh一键安装
curl -L https://arthas.aliyun.com/install.sh | shDocker 环境怎么用
临时诊断
最常用的方式,进容器直接下载:
docker exec -it <container_id> /bin/bash
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar内置到镜像
如果经常需要诊断,可以把 Arthas 打进镜像。Dockerfile 加这几行:
FROM openjdk:8-jdk-alpine
RUN apk add --no-cache curl
RUN curl -O https://arthas.aliyun.com/arthas-boot.jar
COPY app.jar /app.jar
COPY start.sh /start.sh
RUN chmod +x /start.sh
ENTRYPOINT ["/start.sh"]start.sh 内容:
#!/bin/sh
java -jar /app.jar &
sleep 10
if [ "$ENABLE_ARTHAS" = "true" ]; then
java -jar /arthas-boot.jar --target-ip 0.0.0.0 --telnet-port 3658 --http-port 8563 <PID>
fi
wait启动容器:
# 平时不启用
docker run -d my-app
# 需要诊断时启用
docker run -d -e ENABLE_ARTHAS=true -p 3658:3658 -p 8563:8563 my-appDocker Compose 配置:
version: '3'
services:
app:
image: my-app
environment:
- ENABLE_ARTHAS=false
ports:
- "8080:8080"
- "3658:3658"
- "8563:8563"实战场景
CPU 飙高
# 看最忙的 3 个线程
thread -n 3
# 看某个线程在干什么
thread <thread_id>
# 持续监控方法耗时
monitor -c 5 com.example.Service method接口慢
# 追踪调用路径和耗时
trace com.example.Controller handleRequest
# 只追踪耗时超过 100ms 的
trace com.example.Controller handleRequest '#cost > 100'
# 看入参和返回值
watch com.example.Service query "{params,returnObj}" -x 2内存问题
# 看内存使用
memory
# 导出堆转储
heapdump /tmp/dump.hprof
# 实时监控
dashboard类加载问题
# 看类信息
sc -d com.example.MyClass
# 看方法信息
sm com.example.MyClass
# 反编译看源码
jad com.example.MyClass
# 看类加载器
classloader紧急热更新
有次线上出了个空指针,等不及走发布流程,就用 Arthas 热更新救急:
# 1. 反编译获取源码
jad --source-only com.example.Service > Service.java
# 2. 改完代码后编译
mc Service.java -d /tmp
# 3. 重新加载
redefine /tmp/com/example/Service.class注意这只是临时方案,事后还是要正常发版。
实时监控
# 仪表盘,显示线程、内存、GC
dashboard
# 监控方法调用统计
monitor -c 5 com.example.Service method
# 看调用栈
stack com.example.Service method高级用法
Web Console
不想用命令行,可以用浏览器:
java -jar arthas-boot.jar --http-port 8563
# 访问 http://localhost:8563远程诊断
java -jar arthas-boot.jar --tunnel-server 'ws://tunnel-server:7777/ws'批量执行命令
cat > commands.txt << EOF
dashboard
thread -n 3
memory
EOF
java -jar arthas-boot.jar -c commands.txt生产环境注意事项
按需启动
别在镜像里默认启动 Arthas,用环境变量控制:
if [ "$(curl -s http://config-server/arthas/enable)" = "true" ]; then
java -jar arthas-boot.jar &
fi安全加固
# 限制访问 IP
java -jar arthas-boot.jar --target-ip 127.0.0.1
# 设置认证
java -jar arthas-boot.jar --username admin --password secret资源限制
Arthas 本身也吃资源,用的时候注意:
- 高峰期别长时间跑
trace、watch - 用
-n限制输出次数 - 诊断完及时
stop或shutdown
保存诊断结果
# 保存到文件
trace com.example.Service method > /tmp/trace.log
# 用 tt 命令记录调用
tt -t com.example.Service method
tt -i 1000常见问题
Arthas attach 失败
检查 JVM 参数:
-Djdk.attach.allowAttachSelf=trueDocker 容器中无法使用
容器权限不够:
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ...命令执行后没输出
可能是条件表达式不匹配,去掉条件试试:
watch com.example.Service method "{params,returnObj}"最后说两句
Arthas 确实好用,但别把它当监控系统用。开发环境多练练手,生产环境按需启动,诊断完就退出。
我的习惯是:
- 平时结合监控告警快速定位问题
- 遇到紧急情况才上 Arthas
- 诊断完立即保存结果,然后退出释放资源
- 热更新只用来救急,事后一定要正常发版
记住,Arthas 是诊断工具,不是常驻服务。