线上 JVM 故障秒解:Arthas 高阶用法与全链路定位实战指南

简介: 本文介绍阿里巴巴开源的Java诊断工具Arthas在线上JVM故障排查中的核心应用。针对CPU飙高、FullGC频繁、接口超时等常见问题,Arthas提供无需重启服务的热修复能力,包括方法热替换(trace/watch/tt命令)、线程问题定位(thread命令)、内存分析(heapdump)等核心功能。文章通过真实案例演示全链路排查流程,并给出安全使用建议,帮助开发者快速定位和解决线上问题,实现从被动救火到主动定位的转变。Arthas的字节码增强技术可实时监控JVM状态,是提升线上问题排查效率的利器。

线上服务突然CPU飙高100%、接口超时频发、FullGC每隔几分钟一次、线程死锁导致服务卡死、出现异常却没有打印日志,重启服务后问题消失却找不到根因,下次还会复现?传统的jstack、jmap、jhat工具不仅操作繁琐,还需要重启服务、无法热修改代码、线上环境权限受限,根本无法应对分钟级的线上故障。Arthas作为阿里巴巴开源的Java诊断利器,无需重启服务、无需修改代码、全场景覆盖JVM故障排查,是每个Java工程师必备的线上排障神器。本文从高阶核心用法、全链路定位流程、真实线上实战三个维度,带你彻底掌握Arthas,实现线上JVM故障从被动救火到主动定位,从重启解决到根因修复。

Arthas核心工作原理与前置准备

核心工作原理

Arthas的核心是利用JVM的Instrumentation API,在目标JVM进程启动后动态挂载Agent,通过字节码增强技术修改已加载类的字节码,实现方法执行监控、入参出参捕获、类热替换等能力,全程无需停止目标进程,无需修改业务代码,对业务的侵入性极低。

快速安装与启动

使用官方一键安装脚本,直接在目标服务器执行:

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

执行后会列出当前服务器所有运行的Java进程,输入目标进程对应的序号,即可完成attach,进入Arthas交互控制台。

项目环境依赖

本文所有实例基于以下环境构建:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

   <modelVersion>4.0.0</modelVersion>
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>3.2.4</version>
       <relativePath/>
   </parent>
   <groupId>com.jam</groupId>
   <artifactId>demo</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>demo</name>
   <description>Demo project for Arthas Troubleshooting</description>
   <properties>
       <java.version>17</java.version>
       <mybatis-plus.version>3.5.6</mybatis-plus.version>
       <fastjson2.version>2.0.52</fastjson2.version>
       <guava.version>33.1.0-jre</guava.version>
       <springdoc.version>2.5.0</springdoc.version>
   </properties>
   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
           <groupId>com.baomidou</groupId>
           <artifactId>mybatis-plus-boot-starter</artifactId>
           <version>${mybatis-plus.version}</version>
       </dependency>
       <dependency>
           <groupId>com.mysql</groupId>
           <artifactId>mysql-connector-j</artifactId>
           <scope>runtime</scope>
       </dependency>
       <dependency>
           <groupId>com.alibaba.fastjson2</groupId>
           <artifactId>fastjson2</artifactId>
           <version>${fastjson2.version}</version>
       </dependency>
       <dependency>
           <groupId>com.google.guava</groupId>
           <artifactId>guava</artifactId>
           <version>${guava.version}</version>
       </dependency>
       <dependency>
           <groupId>org.springdoc</groupId>
           <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
           <version>${springdoc.version}</version>
       </dependency>
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>1.18.32</version>
           <scope>provided</scope>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
   </dependencies>
   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
               <configuration>
                   <excludes>
                       <exclude>
                           <groupId>org.projectlombok</groupId>
                           <artifactId>lombok</artifactId>
                       </exclude>
                   </excludes>
               </configuration>
           </plugin>
       </plugins>
   </build>
</project>

基础表结构

实例使用MySQL 8.0,表结构如下:

CREATE TABLE `t_order` (
 `order_id` varchar(64) NOT NULL COMMENT '订单ID',
 `user_id` varchar(64) NOT NULL COMMENT '用户ID',
 `amount` decimal(10,2) NOT NULL COMMENT '订单金额',
 `status` tinyint NOT NULL DEFAULT '0' COMMENT '订单状态 0-待支付 1-已支付 2-已取消',
 `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
 PRIMARY KEY (`order_id`),
 KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单表';

核心业务代码

package com.jam.demo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
* 订单实体
* @author ken
* @date 2026-03-16
*/

@Data
@TableName("t_order")
@Schema(description = "订单实体")
public class Order {

   @TableId(type = IdType.ASSIGN_ID)
   @Schema(description = "订单ID")
   private String orderId;

   @Schema(description = "用户ID")
   private String userId;

   @Schema(description = "订单金额")
   private BigDecimal amount;

   @Schema(description = "订单状态")
   private Integer status;

   @Schema(description = "创建时间")
   private LocalDateTime createTime;

   @Schema(description = "更新时间")
   private LocalDateTime updateTime;
}

package com.jam.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jam.demo.entity.Order;
import org.apache.ibatis.annotations.Mapper;

/**
* 订单Mapper接口
* @author ken
* @date 2026-03-16
*/

@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}

package com.jam.demo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.jam.demo.entity.Order;

/**
* 订单服务接口
* @author ken
* @date 2026-03-16
*/

public interface OrderService extends IService<Order> {

   /**
    * 根据订单ID查询订单
    * @param orderId 订单ID
    * @return 订单实体
    */

   Order getOrderById(String orderId);
}

package com.jam.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jam.demo.entity.Order;
import com.jam.demo.mapper.OrderMapper;
import com.jam.demo.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
* 订单服务实现类
* @author ken
* @date 2026-03-16
*/

@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

   @Override
   public Order getOrderById(String orderId) {
       LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
       queryWrapper.eq(Order::getOrderId, orderId);
       return this.getOne(queryWrapper);
   }
}

package com.jam.demo.controller;

import com.jam.demo.entity.Order;
import com.jam.demo.service.OrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

/**
* 订单控制器
* @author ken
* @date 2026-03-16
*/

@Slf4j
@RestController
@RequestMapping("/order")
@Tag(name = "订单管理", description = "订单相关接口")
public class OrderController {

   @Autowired
   private OrderService orderService;

   /**
    * 查询订单详情
    * @param orderId 订单ID
    * @return 订单详情
    */

   @GetMapping("/detail")
   @Operation(summary = "查询订单详情", description = "根据订单ID查询订单详情")
   public Order getOrderDetail(@RequestParam String orderId) {
       log.info("开始查询订单详情,订单ID:{}", orderId);
       Order order = orderService.getOrderById(orderId);
       log.info("查询订单详情完成,订单ID:{}", orderId);
       return order;
   }
}

package com.jam.demo.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* 死锁复现控制器
* @author ken
* @date 2026-03-16
*/

@Slf4j
@RestController
@RequestMapping("/deadlock")
@Tag(name = "死锁复现", description = "死锁复现接口")
public class DeadlockController {

   private static final Object LOCK_A = new Object();
   private static final Object LOCK_B = new Object();

   /**
    * 触发死锁
    */

   @GetMapping("/trigger")
   @Operation(summary = "触发死锁", description = "触发线程死锁,用于Arthas死锁检测演示")
   public String triggerDeadlock() {
       log.info("开始触发死锁");
       Thread thread1 = new Thread(() -> {
           synchronized (LOCK_A) {
               log.info("线程1持有LOCK_A");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   Thread.currentThread().interrupt();
                   log.error("线程1中断", e);
               }
               synchronized (LOCK_B) {
                   log.info("线程1持有LOCK_B");
               }
           }
       }, "Thread-0");

       Thread thread2 = new Thread(() -> {
           synchronized (LOCK_B) {
               log.info("线程2持有LOCK_B");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   Thread.currentThread().interrupt();
                   log.error("线程2中断", e);
               }
               synchronized (LOCK_A) {
                   log.info("线程2持有LOCK_A");
               }
           }
       }, "Thread-1");

       thread1.start();
       thread2.start();
       log.info("死锁触发完成");
       return "死锁已触发";
   }
}

Arthas高阶核心用法

一、热代码替换:线上bug秒修复,无需重启服务

热替换是Arthas最核心的能力之一,支持在线修改已加载类的方法体,无需重启服务,分钟级修复线上bug。这里明确区分两个易混淆的核心命令:

  • retransform:基于Arthas字节码增强框架实现,支持叠加增强,不会重置之前的监控增强,仅支持修改方法体,不支持新增字段/方法/修改方法签名,是线上热修复的首选
  • redefine:直接加载外部编译好的class文件替换JVM已加载类,会重置所有Arthas之前做的增强,适用场景为完全替换类的字节码

完整热修复实战

线上OrderController的getOrderDetail方法存在bug,传入空orderId会触发异常,无需重启服务,通过以下步骤修复:

  1. 反编译获取源代码

jad --source-only com.jam.demo.controller.OrderController > /tmp/OrderController.java

  1. 修改源代码修复bug编辑/tmp/OrderController.java,在方法内添加参数校验逻辑:

@GetMapping("/detail")
@Operation(summary = "查询订单详情", description = "根据订单ID查询订单详情")
public Order getOrderDetail(@RequestParam String orderId) {
   log.info("开始查询订单详情,订单ID:{}", orderId);
   if (!StringUtils.hasText(orderId)) {
       log.error("订单ID不能为空");
       throw new IllegalArgumentException("订单ID不能为空");
   }
   Order order = orderService.getOrderById(orderId);
   log.info("查询订单详情完成,订单ID:{}", orderId);
   return order;
}

  1. 获取类加载器Hash值

sc -d com.jam.demo.controller.OrderController | grep classLoaderHash

  1. 编译修复后的Java文件将上一步获取的hash值替换到-c参数后:

mc -c 1be6f5c0 /tmp/OrderController.java -d /tmp

  1. 热加载修复后的Class文件

retransform /tmp/com/jam/demo/controller/OrderController.class

  1. 验证修复结果调用/order/detail?orderId=接口,会返回规范的参数异常,而非未捕获的空指针,修复完成,全程无服务重启。

热替换核心限制

  • 仅支持修改方法体,不支持新增类的字段、方法、构造函数
  • 不支持修改类的继承关系、实现的接口、方法签名
  • 不支持修改注解、枚举值等类的元信息
  • JVM重启后热修改会失效,永久修复需更新代码重新发布

二、全链路性能追踪:接口超时根因秒定位

针对线上接口超时、慢调用、偶现异常等问题,Arthas提供了trace、watch、tt三大核心命令,无需新增日志,即可全链路观测方法执行的完整上下文。

1. trace:全链路耗时追踪

trace命令用于追踪方法内部的调用链路,统计每个节点的耗时占比,精准定位慢调用代码行,高阶用法如下:

  • 基础追踪:排除JDK内部方法,减少无关输出

trace -j com.jam.demo.controller.OrderController getOrderDetail

执行后调用接口,会输出完整调用链路与耗时分布:

---ts=2026-03-16 10:00:00;thread_name=http-nio-8080-exec-1;id=23;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@1be6f5c0
---[1200ms] com.jam.demo.controller.OrderController:getOrderDetail()
   +---[0.23ms] org.slf4j.Logger:info() #24
   +---[0.05ms] org.springframework.util.StringUtils:hasText() #25
   +---[1195ms] com.jam.demo.service.impl.OrderServiceImpl:getOrderById() #29
   +---[0.18ms] org.slf4j.Logger:info() #31
   ---[0.02ms] return #32

  • 条件过滤:仅追踪耗时超过1000ms的慢调用

trace -j com.jam.demo.controller.OrderController getOrderDetail '#cost > 1000'

  • 多方法递归追踪:同时追踪Controller与Service层的方法

trace -j -E com.jam.demo.controller.OrderController|com.jam.demo.service.impl.OrderServiceImpl getOrderDetail|getOrderById

2. watch:方法上下文全观测

watch命令用于观测方法的入参、出参、返回值、异常对象,甚至方法内部的局部变量,无需新增日志即可获取完整执行上下文:

  • 全场景观测:同时捕获方法执行前、正常返回、异常抛出、执行结束四个节点的上下文

watch com.jam.demo.controller.OrderController getOrderDetail "{params,returnObj,throwExp}" -b -e -s -f

  • 条件过滤:仅观测指定入参的调用

watch com.jam.demo.controller.OrderController getOrderDetail "{params,returnObj}" "params[0].equals('123456')" -s

  • 内部变量观测:查看方法内部的局部变量值

watch com.jam.demo.service.impl.OrderServiceImpl getOrderById "{target, #queryWrapper}" -s

3. tt:时间隧道,偶现问题终极解决方案

tt(TimeTunnel)命令会记录方法的每一次调用的完整上下文,包括入参、出参、异常、耗时、线程信息,支持事后回放、重新调用,完美解决线上偶现问题无法复现的痛点:

  • 开启调用记录

tt -t com.jam.demo.controller.OrderController getOrderDetail

  • 查看所有记录的调用

tt -l

  • 查看指定调用的详细信息(index为记录的序号)

tt -i 1001

  • 回放指定调用,用当时的入参重新执行方法,完美复现问题

tt -i 1001 -p

三、线程问题终极定位:CPU飙高、死锁、阻塞一键排查

Arthas的thread命令基于JVM的ThreadMXBean实现,比传统jstack更强大,支持实时CPU排序、线程状态过滤、死锁自动检测,无需手动分析堆栈。

1. CPU飙高快速定位

线上服务CPU使用率100%,通过以下步骤30秒定位根因:

  1. 查看CPU占用Top3的线程,直接输出线程堆栈

thread -n 3

  1. 输出结果会直接显示高CPU线程的堆栈信息,定位到具体代码行:

"http-nio-8080-exec-2" Id=24 cpuUsage=80.2% RUNNABLE
   at com.jam.demo.service.impl.OrderServiceImpl.calculateOrderAmount(OrderServiceImpl.java:88)
   at com.jam.demo.service.impl.OrderServiceImpl.getOrderById(OrderServiceImpl.java:30)
   at com.jam.demo.controller.OrderController.getOrderDetail(OrderController.java:29)

2. 死锁自动检测

无需手动分析jstack堆栈,一键自动检测死锁:

thread -b

如果存在死锁,会直接输出死锁线程、持有锁对象、等待锁对象、完整堆栈信息:

Found one Java-level deadlock:
=============================
"Thread-1":
 waiting to lock monitor 0x00007f8a9b0c0000 (object 0x0000000700a00000, a java.lang.Object),
 which is held by "Thread-0"
"Thread-0":
 waiting to lock monitor 0x00007f8a9b0c0008 (object 0x0000000700a00008, a java.lang.Object),
 which is held by "Thread-1"

3. 线程状态过滤

查看所有处于阻塞状态的线程,定位线程卡顿根因:

thread --state BLOCKED

四、内存与GC问题深度排查:OOM、FullGC频繁根因定位

针对线上FullGC频繁、内存泄漏、OOM等问题,Arthas提供了完整的排查工具链,无需重启服务,实时查看内存与GC状态,动态修改JVM参数。

1. 全局状态实时查看

dashboard命令实时刷新JVM整体运行状态,是故障排查的第一步:

dashboard

输出内容包括:

  • 堆内存:eden区、survivor区、老年代的容量与使用率
  • 非堆内存:元空间、代码缓存的使用情况
  • GC统计:YoungGC、FullGC的次数与总耗时
  • 线程统计:活跃线程数、守护线程数、峰值线程数
  • CPU使用率:进程CPU、系统CPU使用率

2. GC详情统计

查看GC的详细统计信息,判断GC是否异常:

gc

3. 堆转储与内存泄漏分析

线上出现内存泄漏、FullGC频繁,生成堆转储文件用于深度分析:

heapdump --live /tmp/heapdump.hprof

--live参数仅dumpFullGC后仍存活的对象,排除可回收的垃圾对象,大幅减小dump文件大小,更精准定位内存泄漏。生成的hprof文件可通过MAT、JProfiler等工具分析,找到占用内存最多的对象,定位泄漏根因。

4. 动态修改JVM参数

无需重启服务,动态修改可管理的JVM参数:

# 查看所有JVM参数
vmoption
# 开启OOM时自动生成堆dump
vmoption HeapDumpOnOutOfMemoryError true
# 修改元空间最大大小
vmoption MaxMetaspaceSize 512m

五、类与类加载问题排查:类冲突、代码未生效一键定位

线上出现NoClassDefFoundError、ClassNotFoundException、代码发布后未生效等问题,通过Arthas的sc、sm、jad、classloader命令可快速定位。

1. sc:搜索已加载的类

查看JVM中是否加载了目标类,以及类的详细信息:

# 搜索所有Order相关的类
sc *Order*
# 查看类的详细信息,包括类加载器、源码位置、注解等
sc -d com.jam.demo.controller.OrderController

2. jad:反编译已加载的类

查看JVM中实际运行的源代码,排查代码未生效、类冲突问题:

jad --source-only com.jam.demo.controller.OrderController

3. classloader:类加载器分析

查看类加载器的层级结构、加载的类数量、URL,排查双亲委派破坏、类冲突问题:

# 查看所有类加载器统计信息
classloader
# 查看类加载器层级结构
classloader -t
# 查看指定类加载器加载的所有类
classloader -c 1be6f5c0 -l

六、进阶黑科技:火焰图、动态日志、OGNL万能执行

1. profiler火焰图:性能瓶颈终极定位

Arthas集成了async-profiler,可生成CPU、内存、锁的火焰图,无需重启服务,线上直接使用,精准定位性能瓶颈:

# 启动CPU火焰图采集,时长30秒
profiler start --duration 30 --event cpu
# 查看采集状态
profiler status
# 停止采集,生成HTML格式火焰图
profiler stop --format html

生成的火焰图可直接在浏览器打开,横向宽度代表CPU占用时间,纵向代表调用栈,一眼定位高耗时方法。

2. 动态修改日志级别

线上排查问题需要DEBUG日志,无需重启服务,动态修改日志级别:

# 查看指定类的日志配置
logger -n com.jam.demo.controller.OrderController
# 修改指定类的日志级别为DEBUG
logger -n com.jam.demo.controller.OrderController -l DEBUG
# 修改根日志级别为INFO
logger -l INFO

3. OGNL高阶用法:线上万能执行器

Arthas支持OGNL表达式,可执行任意Java代码,调用Spring Bean、获取静态变量、执行方法,是线上排查的万能工具:

  • 获取Spring容器中的Bean,调用业务方法

ognl '@org.springframework.web.context.ContextLoader@getCurrentWebApplicationContext().getBean("orderServiceImpl").getOrderById("123456")'

  • 获取类的静态变量

ognl '@com.jam.demo.controller.DeadlockController@LOCK_A'

  • 执行数据库查询

ognl '@org.springframework.web.context.ContextLoader@getCurrentWebApplicationContext().getBean("orderMapper").selectById("123456")'

JVM线上故障全链路定位黄金流程

通用排查总流程

分场景详细排查流程

1. CPU飙高排查流程

2. 内存泄漏/FullGC频繁排查流程

3. 接口超时/慢调用排查流程

4. 死锁/线程阻塞排查流程

线上真实故障实战案例

案例一:线上CPU飙高100%,5分钟定位修复

现象:线上服务CPU使用率持续100%,接口响应超时,告警触发,重启服务后10分钟复现。排查过程

  1. Arthas attach目标进程,执行dashboard,看到进程CPU使用率98%,单线程占用85%CPU。
  2. 执行thread -n 1,定位到高耗时代码在OrderServiceImpl的calculateOrderAmount方法,for循环终止条件写错,i--写成i++导致死循环。
  3. 通过jad反编译、mc编译、retransform热修复,CPU使用率立即降至10%以下,接口恢复正常。
  4. 发布正式版本修复,问题彻底解决。

案例二:线上FullGC频繁,10分钟定位内存泄漏

现象:线上服务每3分钟触发一次FullGC,老年代回收后使用率仍达85%,内存持续上涨,最终OOM。排查过程

  1. 执行dashboard,看到老年代使用率2分钟内从50%涨到95%,FullGC频繁。
  2. 执行heapdump --live生成堆转储文件,MAT分析发现100万+Order对象占用1GB内存,被静态List持有。
  3. 通过ognl命令清空静态List,老年代使用率立即降至20%,FullGC停止。
  4. 修复代码移除静态集合,发布正式版本,问题彻底解决。

案例三:线上接口偶现超时,tt命令完美定位

现象:线上订单查询接口偶现超时,每天出现3-5次,无法稳定复现,本地测试正常,无异常日志。排查过程

  1. 执行tt -t记录接口所有调用,等待1小时后捕获到超时调用,index=1008,耗时1200ms。
  2. 执行tt -i 1008 -p回放调用,trace追踪发现数据库查询耗时1190ms。
  3. watch查看SQL语句,发现orderId字段为varchar类型,传入数字类型导致隐式类型转换,索引失效,全表扫描。
  4. 修复代码统一参数类型,发布正式版本,问题彻底解决。

线上使用避坑指南与最佳实践

核心避坑点

  1. 热替换避坑:热修改前必须备份原class文件;生产环境禁止修改核心框架类;排查完成后执行reset命令重置所有增强,避免性能损耗。
  2. 安全规范:生产环境禁止使用stop命令,会重置所有增强类;禁止长时间运行trace、tt等命令,避免占用过多JVM资源;heapdump必须加--live参数,避免磁盘IO打满;禁止执行危险的ognl表达式修改业务数据。
  3. 性能影响:单命令性能损耗低于1%,但同时开启多个增强命令会导致损耗上升,排查完成后必须执行reset重置。
  4. 版本兼容:JDK 9+需开启--enable-native-access参数;SpringBoot 3.x需使用Arthas 3.6.0+版本兼容Jakarta EE。

最佳实践

  1. 故障排查先执行dashboard,整体了解JVM状态,再针对性排查。
  2. 偶现问题优先使用tt命令记录上下文,事后回放复现。
  3. 慢调用优先使用trace命令定位耗时节点,逐层递归排查。
  4. CPU飙高优先使用thread -n命令定位高耗时代码行。
  5. 内存泄漏优先使用heapdump生成堆转储文件,结合MAT分析。
  6. 排查完成后必须执行reset重置所有增强,quit退出Arthas。

总结

Arthas作为Java线上故障排查的神器,覆盖了JVM故障的全场景,从CPU、内存、线程、类加载到接口性能、代码热修复,全程无需重启服务,无需修改代码,极大提升了线上故障排查的效率。本文的高阶用法和全链路定位流程,均经过线上生产环境验证,掌握这些能力,你就能从容应对任何JVM线上故障,从被动救火的业务开发,进阶为能快速定位根因、解决问题的技术专家。

目录
相关文章
|
8天前
|
人工智能 安全 Linux
【OpenClaw保姆级图文教程】阿里云/本地部署集成模型Ollama/Qwen3.5/百炼 API 步骤流程及避坑指南
2026年,AI代理工具的部署逻辑已从“单一云端依赖”转向“云端+本地双轨模式”。OpenClaw(曾用名Clawdbot)作为开源AI代理框架,既支持对接阿里云百炼等云端免费API,也能通过Ollama部署本地大模型,完美解决两类核心需求:一是担心云端API泄露核心数据的隐私安全诉求;二是频繁调用导致token消耗过高的成本控制需求。
5158 9
|
16天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
21095 114
|
7天前
|
JavaScript Linux API
保姆级教程,通过GACCode在国内使用Claudecode、Codex!
保姆级教程,通过GACCode在国内使用Claudecode、Codex!
4636 1
保姆级教程,通过GACCode在国内使用Claudecode、Codex!
|
12天前
|
人工智能 安全 前端开发
Team 版 OpenClaw:HiClaw 开源,5 分钟完成本地安装
HiClaw 基于 OpenClaw、Higress AI Gateway、Element IM 客户端+Tuwunel IM 服务器(均基于 Matrix 实时通信协议)、MinIO 共享文件系统打造。
8061 7
|
14天前
|
人工智能 JavaScript API
保姆级教程:OpenClaw阿里云/本地部署配置Tavily Search skill 实时联网,让OpenClaw“睁眼看世界”
默认状态下的OpenClaw如同“闭门造车”的隐士,仅能依赖模型训练数据回答问题,无法获取实时新闻、最新数据或训练截止日期后的新信息。2026年,激活其联网能力的最优方案是配置Tavily Search技能——无需科学上网、无需信用卡验证,每月1000次免费搜索额度完全满足个人需求,搭配ClawHub技能市场,还能一键拓展天气查询、邮件管理等实用功能。
8061 5