Arthas基础

一、Arthas(阿尔萨斯) 能为你做什么?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。

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

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

二、快速安装

下载arthas-boot.jar,然后用java -jar的方式启动:

curl -O https://alibaba.github.io/arthas/arthas-boot.jar
// 运行命令之前,先运行一个java进程在内存中,不然会出现找不到java进程的错误
java -jar arthas-boot.jar

如果下载速度比较慢,可以使用aliyun的镜像:

java -jar arthas-boot.jar --repo-mirror aliyun --use-http

1、Windows下安装

1、在d:\下创建目录arthas,在windows命令窗口下,使用curl命令下载阿里服务器上的jar包,大小108k
在这里插入图片描述

2、使用java启动arthas-boot.jar,来安装arthas,大小约10M。
运行此命令会发现java进程,输入1按回车。则自动从远程主机上下载arthas到本地目录

3、查看安装好的目录
在这里插入图片描述

2、Linux下安装

1) 从Maven仓库下载全量包
https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/3.1.7/arthas-packaging-3.1.7-bin.zip

2)上传到linux服务器
在这里插入图片描述

3)使用以下命令解压到指定的arthas目录
unzip -d arthas arthas-packaging-3.1.7-bin.zip
在这里插入图片描述

4)启动 arthas-boot.jar
在这里插入图片描述

3、window下卸载 arthas

删除arthas安装目录下的 .arthas 和 logs/arthas logs/arthas-cache
在这里插入图片描述在这里插入图片描述

4、linux下卸载 arthas

三、快速入门:attach一个进程

1、启动一个java进程
arthas 解压的包下面的 arthas-demo.jar
java -jar arthas-demo.jar
在这里插入图片描述

2、启动arthas

  1. 因为arthas-demo.jar进程打开了一个窗口,所以另开一个命令窗口执行arthas-boot.jar
  2. 选择要粘附的进程:arthas-demo.jar —》1
    在这里插入图片描述
    如果端口号被占用,也可以通过以下命令换成另一个端口号执行
    java -jar arthas-boot.jar --telnet-port 9998 --http-port -1

四、基础命令

1、help

查看命令帮助信息

2、cat

打印文件内容,和linux里的cat命令类似

3、grep

匹配查找,和linux里的grep命令类似,但它只能用于管道命令

4、pwd

返回当前的工作目录,和linux命令类似

5、cls

清空当前屏幕区域

6、session

查看当前会话的信息
在这里插入图片描述

7、reset

重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类

8、version

输出当前目标 Java 进程所加载的 Arthas 版本号

9、quit

退出当前 Arthas 客户端,其他 Arthas 客户端不受影响

10、stop

关闭 Arthas 服务端,所有 Arthas 客户端全部退出

11、keymap

Arthas快捷键列表及自定义快捷键

五、jvm相关命令

1、dashboard

显示当前系统的实时数据面板,按q或ctrl+c退出
在这里插入图片描述

数据说明

  • ID: Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
  • NAME: 线程名
  • GROUP: 线程组名
  • PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
  • STATE: 线程的状态
  • CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
  • TIME: 线程运行总时间,数据格式为分:秒
  • INTERRUPTED: 线程当前的中断位状态
  • DAEMON: 是否是daemon线程

2、thread线程相关

查看当前 JVM 的线程堆栈信息

在这里插入图片描述

  • thread -n 3:展示当前最忙的前3个线程并打印堆栈
  • thread: 当没有参数时,显示所有线程的信息
  • thread xxx:显示xxx线程的运行堆栈
    在这里插入图片描述
  • thread -b : 找出当前阻塞其他线程的线程
    找出当前阻塞其他线程的线程,有时候我们发现应用卡住了, 通常是由于某个线程拿住了某个锁, 并且其他线程都在等待这把锁造成 的。 为了排查这类问题, arthas提供了thread -b, 一键找出那个罪魁祸首。
public class DeadLockTest {

    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Thread 1 acquired lock1");
                try {
                    Thread.sleep(100); // 让线程1休眠一段时间,让线程2有机会获取lock2
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread 1 waiting for lock2");
                synchronized (lock2) {
                    System.out.println("Thread 1 acquired lock2");
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("Thread 2 acquired lock2");
                System.out.println("Thread 2 waiting for lock1");
                synchronized (lock1) {
                    System.out.println("Thread 2 acquired lock1");
                }
            }
        });

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Both threads completed execution");
    }
}

在这里插入图片描述

  • thread -i 1000 -n 3:指定采样时间间隔,每过1000毫秒采样,显示最占时间的3个线程
  • thread --state WAITING: 查看处于等待状态的线程

3、jvm

查看当前 JVM 的信息

4、sysprop

查看和修改JVM的系统属性

  • 查看所有属性:sysprop
  • 查看单个属性,支持通过tab补全: sysprop java.version
  • 修改单个属性:sysprop user.country CN
    在这里插入图片描述

5、sysenv

查看当前JVM的环境属性( System Environment Variables )

  • 查看所有环境变量:sysenv
  • 查看单个环境变量:sysenv USER

6、vmoption

查看,更新VM诊断相关的参数

查看所有的选项
vmoption
查看指定的选项
vmoption PrintGCDetails
更新指定的选项
vmoption PrintGCDetails true

7、getstatic

通过getstatic命令可以方便的查看类的静态属性

语法:getstatic 类名 属性名

8、ognl

执行ognl表达式,这是从3.0.5版本新增的功能

六、class/classloader相关命令

1、sc

“Search-Class” 的简写,这个命令能搜索出所有已经加载到 JVM 中的Class 信息

2、sm

“Search-Method” 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。
在这里插入图片描述

3、jad

反编译指定已加载类的源码。

jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻辑;

在这里插入图片描述
反编绎时只显示源代码,默认情况下,反编译结果里会带有ClassLoader信息,通过–source-only选项,可以只打印源代码。方便和mc/redefine命令结合使用。
jad --source-only demo.MathGame

4、mc

Memory Compiler/内存编译器,编译 .java 文件生成 .class

在内存中编译Hello.java为Hello.class
mc /mysoft/arthas/Hello.java
在这里插入图片描述

可以通过-d命令指定输出目录
mc -d /mysoft/arthas /mysoft/arthas/Hello.java

5、redefine

加载外部的 .class 文件,redefine到JVM里

【案例】结合 jad/mc 命令使用

  1. 使用jad反编译demo.MathGame输出到/root/MathGame.java
    jad --source-only demo.MathGame > /root/MathGame.java

  2. 对/root/MathGame.java进行编辑
    在这里插入图片描述

  3. 使用mc内存中对新的代码编译
    mc /root/MathGame.java -d /root

  4. 使用redefine命令加载新的字节码
    redefine /root/demo/MathGame.class

在这里插入图片描述
在这里插入图片描述

  • 19
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值