不重启服务排查线上 Java 问题(Arthas)
Arthas 是阿里巴巴开源的 Java 诊断工具,通过 attach 挂到运行中的 JVM,不改代码、不重启服务就能查看类加载、方法调用、线程与 GC 状态。这篇文章拆解它的 attach 与字节码增强机制、主要命令的用法与限制,也说明它在容器与 Kubernetes 环境下的接入变化,帮你在临时排查和平台化诊断之间做出选型。
线上 Java 服务出故障时,本地开发环境常常连不上生产网络,用 IDE 远程调试又会挂起所有线程,业务跟着停摆。把问题挪到测试环境复现,有些故障换个环境就不出现,进程一重启更是没了痕迹。想加日志,得走测试、预发、上线整条链路,等看到结果,故障窗口早过去了。
Arthas 的切入点是绕开这套流程。它以观察者的身份挂到正在运行的 JVM 上,排查过程不重启进程,也不暂停已有线程,更不需要改业务代码重新发布。
Arthas 是阿里巴巴开源的 Java 诊断工具,用 Java 编写。挂载到运行中的 JVM 后,无需改动代码或重启服务,即可用命令行查看类加载、方法调用与线程、GC 状况。
它怎么做到的
启动 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 的部署方式和限制,作者已注明未逐一核实。正文未给出可复现的测试环境,增强带来的性能开销量级也没有数据。用户反馈摘要
根据仓库 Issue 来看,多数提交者分享的是实战用例:用 trace 把接口耗时从数百毫秒压到几十毫秒,用 thread 定位 CPU 打满,活用 OGNL 表达式,借 tt 取到 Spring Context,用 redefine 追查异常日志来源;也有人整理常用命令速查图,或把 Arthas 接进 SpringBoot Admin 与内部在线诊断平台。共识是命令覆盖够用、OGNL 要专门学;待解决的包括 Arthas 4.0 的 bytekit 计划、源码分析连载,以及一条长期征集使用者的 Issue。
基于该仓库公开 Issue 整理,只反映提交者报告的现象与诉求,不代表诀.com 立场,也不代表问题已被确认。项目来源与说明
开源项目:alibaba(alibaba)
本文由诀.com 编辑基于该项目的公开信息独立撰写,属原创解读,不是对项目文档的翻译或转载;文中提到的功能与参数以官方仓库为准,代码与文档版权归原作者所有。
查看项目仓库