不重启服务排查线上 Java 问题(Arthas)

Arthas 是阿里巴巴开源的 Java 诊断工具,通过 attach 挂到运行中的 JVM,不改代码、不重启服务就能查看类加载、方法调用、线程与 GC 状态。这篇文章拆解它的 attach 与字节码增强机制、主要命令的用法与限制,也说明它在容器与 Kubernetes 环境下的接入变化,帮你在临时排查和平台化诊断之间做出选型。

线上 Java 服务出故障时,本地开发环境常常连不上生产网络,用 IDE 远程调试又会挂起所有线程,业务跟着停摆。把问题挪到测试环境复现,有些故障换个环境就不出现,进程一重启更是没了痕迹。想加日志,得走测试、预发、上线整条链路,等看到结果,故障窗口早过去了。

Arthas 的切入点是绕开这套流程。它以观察者的身份挂到正在运行的 JVM 上,排查过程不重启进程,也不暂停已有线程,更不需要改业务代码重新发布。

Arthas 是阿里巴巴开源的 Java 诊断工具,用 Java 编写。挂载到运行中的 JVM 后,无需改动代码或重启服务,即可用命令行查看类加载、方法调用与线程、GC 状况。

Arthas 是阿里巴巴开源的 Java 诊断工具,用 Java 编写。挂载到运行中的 JV

它怎么做到的

启动 arthas-boot.jar 之后,Arthas 会挂载到目标 JVM 上,命令的输入输出走 telnet 与 websocket 通道,命令行和浏览器两种界面都能用。诊断动作在目标进程内部执行,取到的数据直接来自 JVM 运行时:已加载的类、类加载器层次、线程栈与状态、GC 统计、方法调用时的参数与返回值。

需要看到方法内部行为时,靠的是字节码增强。retransform 把外部 .class 文件加载进 JVM,替换已加载的类;trace、watch、monitor 这类命令在目标方法上插入探针,拦截调用并统计。仓库未展开说明增强使用的字节码框架;Issue 里的 Arthas 4.0 计划提到要提供一个名为 bytekit 的框架,截至目前这一条仍列在待办中。

结果回到客户端:终端里打印表格或堆栈,Web Console 里呈现同样的输出。profiler 与火焰图用于热点定位,具体输出形式见官方文档。

几个关键设计

attach 与跨容器接入

最省事的接入方式是下载 arthas-boot.jar 后用 java 启动:

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

查看用法用 java -jar arthas-boot.jar -h。Linux、Unix、Mac 上还有一行安装脚本,会把引导脚本 as.sh 下载到当前目录,你可以移到任意位置,或放进 $PATH:

curl -L https://arthas.aliyun.com/install.sh | sh

执行 as.sh 进入交互界面,as.sh -h 看更多帮助。

容器化环境的接入在这两年有明显变化。4.3.4 起,Arthas 支持从 Kubernetes 临时调试容器跨 mount namespace attach 目标 JVM,自动处理 attach socket、Arthas Home 复制与清理,目标服务启动失败时给出明确诊断。4.3.5 补上了 Kubernetes 临时调试容器与 sidecar 跨容器 attach 的指南文档。4.3.3 把 Docker 构建的基础镜像换成 Amazon Corretto 8 Alpine,修复了多架构镜像构建的兼容性问题。

从类到方法的排查命令

命令覆盖的粒度,从「类有没有被加载」一直延伸到「方法被谁调用、耗时多少」。

  • sc 搜索已加载的类,sc -d org.springframework.web.context.support.XmlWebApplicationContext 会打印 code-source、类加载器、修饰符等信息,jar 包冲突时靠它定位类到底从哪个包加载。
  • jad 反编译类,例如 jad javax.servlet.Servlet,用来确认线上跑的代码和预期是否一致。
  • thread -n 3 按 CPU 占用排名给出前三个线程的堆栈。
  • trace 追踪方法调用链路,找出耗时的子调用;watch 查看调用的入参、返回对象与抛出的异常;monitor 统计调用次数、qps、rt 和成功率;stack 查指定方法的调用来源。
  • mc 在内存里编译 .java 文件,例如 mc /tmp/Test.java;retransform 把 .class 文件加载进 JVM 做热替换,带类加载器时写 retransform -c 327a647b /tmp/Test.class /tmp/Test\$Inner.class。
  • vmtool 取堆中指定类的实例对象,dashboard 汇总系统指标、线程状态与 GC 统计。

表达式求值与增强边界

3.0 版本用 OGNL 表达式替换了 groovy 做表达式求值,官方给的理由是规避 groovy 潜在的内存泄露。OGNL 另有一套写法,社区里有人专门收集它的特殊用法,官方文档也在 4.3.5 补了复杂 OGNL 表达式指南,并从相关命令与 API 文档统一链接过去。

增强有一条默认边界:java.* 这类系统级别的类默认不能被增强,需要打开 unsafe 开关,官方在这条说明里附了「增强系统类时请谨慎操作」的提醒。

命令行之外的多形态接入

telnet 与 websocket 让同一套命令既能本地用,也能远程用,命令行和浏览器都接。仓库里有 arthas-mcp-server 模块,4.3.3 新增的 MCP upload_file 工具可以把 .class、.java、.jfc 小文件上传到目标 JVM 的文件系统,供后续诊断工具使用。arthas-spring-boot-starter 模块对应官方文档里的 Spring Boot Starter 页面,arthas-external-command 与 arthas-demo-external-command 用于编写和演示外部命令。这几个模块的具体用法,README 没有展开说明。

这样设计的代价

attach 是整套机制的前提,也因此成了第一道门槛。你需要一条能连到目标 JVM 的通道,以及对应的进程权限。跨用户、跨容器时,attach socket 的权限与 namespace 隔离会直接拦住你。Issue 里两类高频问题都出自这里:「Unable to open socket file: target process not responding or HotSpot VM not loaded」和「attach to target jvm (*) failed」,两条目前都标记为已解决。

系统类默认禁用增强,是安全优先的默认值。代价是排查 JDK 自身相关行为时,你得先打开 unsafe 开关,而这个开关本身就带着操作风险。

命令数量多,还要额外学一套 OGNL 表达式语法。社区里那条「活用 ognl 表达式」的长贴有 25 条评论,说明这部分确实要专门花时间。官方为此把在线教程按命令拆成一个个小教程,每个命令一份。

仓库体积 73522 KB,指的是仓库本身的大小,与运行时内存占用无关。增强带来的性能开销量级,README 没有给出说明。

同类工具横向对照

下面两个项目在 Java 生产问题诊断这件事上和 Arthas 有重合,属于能解决部分相同问题的同类:都面向运行中的 Java 应用排查,区别在形态上,一个偏命令行单进程接入,一个偏一站式诊断方案。

项目适合谁部署方式主要限制什么情况下选它更合适项目地址
Arthas需要临时登上目标机器、排查单个 JVM 的 Java 后端开发与 SRE下载 arthas-boot.jar 用 java 启动,或用 as.sh 安装脚本;容器场景用 4.3.4 之后的跨 mount namespace attach系统类增强默认关闭,需打开 unsafe 开关;仓库里没有多实例集中管控的说明只想临时 attach 一个进程、不想额外搭服务时alibaba/arthas
Bistoury要给多台机器搭统一诊断入口的团队仓库没有说明未逐一核实需要集中管理多实例的诊断入口时qunarcorp/bistoury
BistouryX关注 Bistoury 衍生版本、同样想要平台化诊断的团队仓库没有说明未逐一核实需要集中管理多实例的诊断入口时xopencode/bistouryX

Bistoury 与 Arthas 在能力上有重合,都做 Java 生产问题的诊断,区别在形态。Arthas 是逐个进程 attach 的命令行工具,Bistoury 的定位是一站式诊断方案。要给一批实例搭统一入口、由平台集中下发命令,Arthas 没有这层能力,Bistoury 这条路更贴合。只是临时登一台机器看一个进程,Arthas 不需要额外搭任何服务。

对你的实际影响

最直接的变化是排障路径缩短。改动代码、走发布流程、再加日志这一圈可以省掉,问题现场还能保留。

权限准备要提前做。你需要登录目标机器的能力,以及目标 JVM 运行用户的身份。Kubernetes 环境下,4.3.4 之后可以用临时调试容器跨 mount namespace 接入,4.3.5 又补了操作指南,比早期版本少踩一些坑。

遇到「命令找不到类或方法」时,排查顺序是先确认类已经被 JVM 加载。sc 和 sm 能搜到结果,说明类已加载;搜不到,多半是还没触发加载。目标是 java.* 系统类时,回到 unsafe 开关那一步。

Arthas 的用途是诊断自有或已授权的 Java 进程。attach 到不属于自己的服务做字节码增强,可能违反服务条款,也可能带来法律风险,别把它当成越权排查的手段。

需要临时登上一台机器、定位某个进程的线上问题,Arthas 够用,装上就能跑。要长期给一批实例做集中诊断、由平台统一下发和收集,它没有这层能力,得看别的方案。命令清单和用法在 arthas.aliyun.com 上有完整说明。

焚评:这个项目的量化评分

本项目的选题来自 焚.com(一个按公开公式给 GitHub 项目打分的站)。焚评当前总分 9.8 分(满分 10)。下表是各维度的得分:

评分维度得分
热度动量(权重 25%)10.0 / 10
开发活跃(权重 25%)10.0 / 10
社区响应(权重 15%)8.9 / 10
文档质量(权重 15%)10.0 / 10
发布节奏(权重 10%)9.3 / 10
风险控制(权重 10%)10.0 / 10

评分口径、权重与计算方式见焚.com 的评分方法页;数据随 GitHub 指标刷新,具体数值以焚.com 当前页面为准。本文正文为诀.com 独立撰写,评分数据由焚.com 授权引用。

内容核验说明

线上 Java 排障的工具选型里,attach 机制、命令边界和容器接入这三件事最容易被略过,本文把它们讲清了,还标出系统类增强默认关闭、unsafe 开关自带风险这类限制,适合需要临时登上机器看进程的后端与 SRE。版本号、Issue 状态和评分都来自外部引用,未独立验证;对比表中 Bistoury 两项作者已注明未核实,选型前要自己确认。

文中的版本号、Issue 状态、仓库体积等信息来自 alibaba/arthas 仓库及其 Issue 的公开内容,焚评评分由焚.com 授权引用,诀.com 均未独立验证。Bistoury 与 BistouryX 的部署方式和限制,作者已注明未逐一核实。正文未给出可复现的测试环境,增强带来的性能开销量级也没有数据。

项目来源与说明

开源项目:alibaba(alibaba)

本文由诀.com 编辑基于该项目的公开信息独立撰写,属原创解读,不是对项目文档的翻译或转载;文中提到的功能与参数以官方仓库为准,代码与文档版权归原作者所有。

查看项目仓库