找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

679

积分

1

好友

83

主题
发表于 前天 06:06 | 查看: 8| 回复: 0

Arthas是一款线上监控诊断产品,通过全局视角实时查看应用load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。

当遇到以下类似问题而束手无策时,Arthas可以为你提供帮助:

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  5. 是否有一个全局视角来查看系统的运行状况?
  6. 有什么办法可以监控到 JVM 的实时运行状态?
  7. 怎么快速定位应用的热点,生成火焰图?
  8. 怎样直接从 JVM 内查找某个类的实例?

Arthas是一个Java应用,它启动后能够自动搜索本机部署的Java进程,并可以作为一个观察者持续观察我们的Java进程。Arthas作为观察者能够实时监控大整个JVM运行状态信息,小到类的运行状态,方法的运行状态信息。除此之外,Arthas能够让我们在不停机的情况下实现代码热更新,以及动态开启日志等功能,这对我们排查线上问题十分有用。

演示环境

  • jdk1.8
  • centos7

Arthas支持 JDK 6+(4.x 版本不再支持 JDK 6 和 JDK 7),支持 Linux/Mac/Windows.

启动测试程序

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

math-game是Arthas官网提供的一个普通Demo,用于测试Arthas的功能。源码如下:

package demo;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

public class MathGame {
    private static Random random = new Random();
    private int illegalArgumentCount = 0;

    public static void main(String[] args) throws InterruptedException {
        MathGame game = new MathGame();
        // 无限循环生成
        while (true) {
            game.run();
            TimeUnit.SECONDS.sleep(1);
        }
    }

    public void run() throws InterruptedException {
        try {
            // 生成随机数
            int number = random.nextInt()/10000;
            // 获取分解质因数结果
            List<Integer> primeFactors = primeFactors(number);
            // 打印分解质因数结果
            print(number, primeFactors);
        } catch (Exception e) {
            System.out.println(String.format("illegalArgumentCount:%3d, ", illegalArgumentCount) + e.getMessage());
        }
    }

    //打印方法
    public static void print(int number, List<Integer> primeFactors) {
        StringBuffer sb = new StringBuffer(number + "=");
        for (int factor : primeFactors) {
            sb.append(factor).append('*');
        }
        if (sb.charAt(sb.length() - 1) == '*') {
            sb.deleteCharAt(sb.length() - 1);
        }
        System.out.println(sb);
    }

    // 根据传入参数对其分解质因数,返回分解质因数列表
    // 比如传入参数为3 返回值为【3】
    //传入参数为10 返回值为【2,5】
    // 传入参数小于2 ,抛出 IllegalArgumentException异常
    public List<Integer> primeFactors(int number) {
        if (number < 2) {
            illegalArgumentCount++;
            throw new IllegalArgumentException("number is: " + number + ", need >= 2");
        }
        List<Integer> result = new ArrayList<Integer>();
        int i = 2;
        while (i <= number) {
            if (number % i == 0) {
                result.add(i);
                number = number / i;
                i = 2;
            } else {
                i++;
            }
        }
        return result;
    }
}

这个程序逻辑很简单:main()方法为入口,一个while循环无限执行run()方法,每次执行完睡眠一秒。run()方法内部首先生成一个随机数,然后调用primeFactors()方法对随机数分解质因数,最后调用print()方法打印结果。

启动demo后,会在控制台持续打印类似如下的信息:

图片

每一行代表一次执行结果,例如第一行提示参数非法,当前参数为-200534,需要大于2;第三行打印的是209949分解质因数的结果。

启动Arthas

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

启动后,控制台会列出检测到的Java进程:

图片

输入目标Java程序前面对应的序号(这里是1)并回车,Arthas便会附着到该进程上。成功连接后,会看到以下界面:

图片

至此,测试环境准备就绪。

Arthas常用命令

提示:必须在Arthas成功连接目标程序后,才能执行其命令。Arthas支持Tab键命令补全。

help

帮助命令,列出所有可用命令及其简介。 图片

-h

几乎所有Arthas命令都支持-h参数,用于查看该命令的详细用法。 图片

也可以直接查阅Arthas官网的中文命令文档:https://arthas.aliyun.com/doc/commands.html

dashboard

仪表盘命令,用于从整体视角展示系统状态统计信息,包括线程、内存、GC和运行时数据。 图片

常用参数

  • -i 刷新实时数据的时间间隔 (ms),默认 5000ms
  • -n 刷新实时数据的次数

例如,dashboard -i 2000 -n 2 表示每隔2秒刷新一次,只刷新两次后自动结束。

thread

查看线程相关信息。

  • thread 显示第一页线程信息。 图片
  • thread --all 显示所有线程信息。
  • thread id 显示指定线程ID的堆栈信息。
  • thread -n 3 查看最忙的三个线程堆栈信息。
  • thread -b 检测死锁(目前主要支持 synchronized 关键字导致的死锁)。

sc (Search Class)

搜索JVM已加载的类信息。

sc -d demo.MathGame  #查看MathGame类的详细信息,-d代表详细信息

图片

sm (Search Method)

搜索JVM已加载的方法信息。

sm -d demo.MathGame  #查看MathGame类的方法详细信息

图片

jad

反编译命令,将指定的类或方法反编译为Java代码。用于确认线上运行的代码版本。

  • jad demo.MathGame 反编译MathGame类。 图片
  • jad demo.MathGame primeFactors 仅反编译primeFactors方法。
  • jad demo.MathGame --source-only 仅输出源码,不包含类加载器信息。

mc (Memory Compile)

内存编译,类似于javac命令,将.java文件编译为.class文件。

mc /path/to/Some.java -d /output/dir

redefine

重新定义类,将外部的.class文件热加载到JVM中,实现代码热更新。

redefine /path/to/Some.class

注意redefine的限制

  • 不能修改、添加、删除类的字段和方法(包括方法签名)。
  • 正在执行的方法不会立即生效。
  • watch/trace/jad/tt等命令可能存在冲突。

jad | mc | redefine 实现热更新

这三个命令组合可以实现无需重启的代码热更新。

  1. 反编译线上类到文件:
    jad demo.MathGame --source-only > /tmp/MathGame.java
  2. 编辑/tmp/MathGame.java文件,修改代码。
  3. 编译修改后的Java文件:
    mc /tmp/MathGame.java -d /tmp/
  4. 重新加载编译后的Class文件到JVM:
    redefine /tmp/demo/MathGame.class

执行成功后,线上程序的逻辑会立即更新。

watch

观察方法的执行情况,查看入参、返回值、异常、对象属性等。 基本语法:watch 全限定类名 方法名 “观察表达式”

例如,观察primeFactors方法的参数、目标对象、返回值和异常:

watch demo.MathGame primeFactors '{params, target, returnObj, throwExp}'

图片

观察表达式使用OGNL语法。添加 -x 参数可以指定对象展开层级(默认为1):

watch demo.MathGame primeFactors '{params, target, returnObj, throwExp}' -x 2

更多用法请参考官方文档:https://arthas.aliyun.com/doc/watch.html

trace

追踪方法内部调用路径,并输出每个节点的耗时,用于性能瓶颈定位。

trace demo.MathGame run

图片

默认不包含JDK方法,添加--skipJDKMethod false可以包含。更多用法:https://arthas.aliyun.com/doc/trace.html

tt (Time Tunnel)

时间隧道命令。记录下指定方法每次调用的现场信息(参数、返回值、异常等),并可对这些记录进行事后查看甚至重放。

  • tt -t demo.MathGame run 开始记录run方法的调用。 图片
  • tt -l 列出所有记录。
  • tt -i 1000 查看索引为1000的记录的详细信息。
  • tt -p -i 1000 重放索引为1000的方法调用。
  • tt -d -i 1000 删除指定记录。
  • tt --delete-all 清除全部记录。

heapdump

生成JVM堆内存转储文件(类似jmap -dump功能)。

heapdump /tmp/dump.hprof

图片

生成的.hprof文件可以使用MAT(Memory Analyzer Tool)等工具进行分析,排查内存泄漏等问题。注意:此操作可能对应用性能产生影响,建议在业务低峰期执行。

总结

Arthas是一个功能强大的Java诊断工具,能够帮助开发者在不重启应用的前提下,高效地排查线上问题、监控应用状态、定位性能瓶颈。本文仅介绍了部分核心命令,Arthas官方提供了多达45个命令,更多高级功能和详细用法,请参考Arthas官方文档。熟练掌握Arthas,将极大提升你的线上运维和问题排查能力。




上一篇:C语言编程入门实战:在Visual Studio 2019中创建并运行首个Hello World程序
下一篇:Python实战:通过Docker容器连接并查询elabFTW数据库
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-11 05:10 , Processed in 0.094469 second(s), 37 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表