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 | sh

Docker 环境怎么用

临时诊断

最常用的方式,进容器直接下载:

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-app

Docker 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 本身也吃资源,用的时候注意:

  • 高峰期别长时间跑 tracewatch
  • -n 限制输出次数
  • 诊断完及时 stopshutdown

保存诊断结果

# 保存到文件
trace com.example.Service method > /tmp/trace.log

# 用 tt 命令记录调用
tt -t com.example.Service method
tt -i 1000

常见问题

Arthas attach 失败

检查 JVM 参数:

-Djdk.attach.allowAttachSelf=true

Docker 容器中无法使用

容器权限不够:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ...

命令执行后没输出

可能是条件表达式不匹配,去掉条件试试:

watch com.example.Service method "{params,returnObj}"

最后说两句

Arthas 确实好用,但别把它当监控系统用。开发环境多练练手,生产环境按需启动,诊断完就退出。

我的习惯是:

  • 平时结合监控告警快速定位问题
  • 遇到紧急情况才上 Arthas
  • 诊断完立即保存结果,然后退出释放资源
  • 热更新只用来救急,事后一定要正常发版

记住,Arthas 是诊断工具,不是常驻服务。

标签: none

添加新评论