四、Arthas

2023-11-15

四、Arthas

    1、安装/卸载

        (1)、Arthas支持在Linux/Unix/Mac等平台上一键安装,请复制以下内容,并粘贴到命令行中,敲回车执行即可。

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

            上述命令会下载启动脚本文件as.sh到当前目录,你可以放在任何地方或将其加入到$PATH中。直接在shell下面执行./as.sh,就会进入交互界面。也可以执行./as.sh -h来获取更多参数信息。

Das

        (2)、卸载

            在Linux/Unix/Mac平台删除下面文件。

rm -rf ~/.arthas/

rm -rf ~/logs/arthas

    2、运行

        执行:java -jar arthas-boot.jar 运行Arthas,粘附到指定Java应用进程

    3、命令

        (1)、基础命令

            help——查看命令帮助信息

            cls——清空当前屏幕区域

            session——查看当前会话的信息

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

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

            history——打印命令历史

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

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

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

        (2)、常用命令

            命令列表:命令列表 | arthas

            ①、dashboard 查看仪表盘,按Q或Ctrl + C可以中断执行。

            ②、thread 获取该进程的所有线程

                thread 1 查看序号为1线程的内容

            ③、jad java.lang.Object 反编译Object类方便查看

    4、源码分析

        (1)、arthas-boot模块

            ①、输入命令:java -jar arthas-boot.jar 或 ./as.sh

            ②、运行arthas-boot.jar中com.taobao.arthas.boot.Bootstrap#main方法,或者运行as.sh文件

            ③、获取arthas版本信息

            ④、解析命令传入参数,将参数解析成CommandLine对象

            ⑤、设置镜像仓库,日志打印等

            ⑥、端口校验是否被占用

            ⑦、获取pid,校验目标端口的pid和attach pid是否一致

            ⑧、获取arthas home,启动arthas-core.jar

        (2)、arthas-core模块

            ①、运行arthas-boot.jar中com.taobao.arthas.core.Arthas#main

            ②、将透传的参数解析转换成CommandLine对象

            ③、获取VirtualMachine.list()列表,匹配目标进程pid

            ④、利用VirtualMachine.attach(),attach到目标进程

            ⑤、利用virtualMachine.loadAgent()方法加载agent的jar包arthas-agent.jar 

        (3)、arthas-agent模块(从这开始所有代码都是运行在目标JVM中)

            ①、运行arthas-agent.jar中com.taobao.arthas.agent334.AgentBootstrap#main

            ②、对传递的参数解析

            ③、通过反射执行com.taobao.arthas.core.server.ArthasBootstrap#getInstance(Instrumentation ins, String args)方法,初始化spy和arthas命令

            ④、将arthas-spy.jar添加到BootstrapClassLoader加载目录下,解决一些ClassLoader加载不到SpyAPI的问题,加载SpyAPI,通过字节码插入到业务代码的逻辑类在arthas-spy.jar包

            ⑤、初始化arthas运行的环境变量

        (4)、arthas-spy.jar包

            ①、SpyAPI当中的6个“at…”静态方法都调用了实例spyInstance中对应的方法。spyInstance的静态类型是抽象类AbstractSpy,抽象类AbstractSpy当中有六个抽象方法。当SpyAPI被加载时,它的静态语句会将spyInstance设置为类NopSpy的实例,其中这NopSpy继承自AbstractSpy并且实现的每个方法都是空操作。

            ②、AbstractSpy抽象类

public static abstract class AbstractSpy {
    // 进入
    public abstract void atEnter(Class<?> clazz, String methodInfo, Object target, Object[] args);
    // 退出
    public abstract void atExit(Class<?> clazz, String methodInfo, Object target, Object[] args, Object returnObject);
    // 异常退出
    public abstract void atExceptionExit(Class<?> clazz, String methodInfo, Object target, Object[] args, Throwable throwable);
    // 调用前
    public abstract void atBeforeInvoke(Class<?> clazz, String invokeInfo, Object target);
    // 调用后
    public abstract void atAfterInvoke(Class<?> clazz, String invokeInfo, Object target);
    // 异常调用
    public abstract void atInvokeException(Class<?> clazz, String invokeInfo, Object target, Throwable throwable);
}

            ③、Enhancer类

                对类进行通知增强,继承ClassFileTransformer,并实现transform方法

public class Enhancer implements ClassFileTransformer {
    // 通过静态代码块初始化SpyAPI
    static {
        SpyAPI.setSpy(spyImpl);
    }

    @Override
    public byte[] transform(final ClassLoader inClassLoader, String className, Class<?> classBeingRedefined,
            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        try {
            // 检查classloader能否加载到 SpyAPI,如果不能,则放弃增强
            try {
                if (inClassLoader != null) {
                    inClassLoader.loadClass(SpyAPI.class.getName());
                }
            } catch (Throwable e) {
                logger.error("the classloader can not load SpyAPI, ignore it. classloader: {}, className: {}",
                        inClassLoader.getClass().getName(), className, e);
                return null;
            }
        }
        ...
        return null;
    }
}

参考文章:

        (1)、消失的堆栈:消失的堆栈

        (2)、JVM Attach机制:JVM Attach机制实现 - 你假笨

        (3)、Arthas原理一:Arthas原理系列(一):利用JVM的attach机制实现一个极简的watch命令

        (4)、Arthas原理二:Arthas原理系列(二):总体架构和项目入口

        (5)、Arthas原理三:Arthas原理系列(三):服务端启动流程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

四、Arthas 的相关文章

  • SPNEGO 密码身份验证问题

    我已将我的应用程序配置为通过 SPNEGO 与 Websphere 使用 Kerberos 身份验证 这是详细信息 krb5 conf libdefaults default realm ABC MYCOMPANY COM default
  • 将构造函数作为参数传递给方法

    我是java新手 开始研究构造函数 我看到一些构造函数作为参数传递给方法的示例 请告诉我当构造函数作为参数传递给方法时会发生什么 或者建议我一些链接 我可以在其中获得有关使用构造函数的足够知识 根据您需要传递构造函数的目的 您可以考虑传递供
  • 将 MouseListener 添加到面板

    我正在尝试将鼠标操作添加到我的面板中 这就是程序应该做的事情 编写一个程序 允许用户通过按三下鼠标来指定一个三角形 第一次按下鼠标后 画一个小点 第二次按下鼠标后 绘制一条连接前两个点的线 第三次按下鼠标后 绘制整个三角形 第四次按下鼠标会
  • 如何作为应用程序发布到页面?

    所以 我有一个应用程序 Facebook 应用程序实体 并且我有一个页面 我想使用应用程序通过java代码 通过restfb或任何其他建议 发布到页面 看起来我错过了页面授予应用程序发布权限的阶段 不知道该怎么做 谢谢你们 乌里 您只能 作
  • 使用 Apache POI Excel 写入特定单元格位置

    如果我有一个未排序的参数 x y z 列表 是否有一种简单的方法将它们写入使用 POI 创建的 Excel 文档中的特定单元格 就好像前两个参数是 X 和Y 坐标 例如 我有如下行 10 4 100 是否可以在第 10 行第 4 列的单元格
  • 迭代函数可以调用自身吗?

    当观看下面的 MIT 6 001 课程视频时 讲师在 28 00 将此算法标记为迭代 但是 在 30 27 他说这个算法和实际的 递归 算法都是递归的 该函数正在使用基本情况调用自身 那么这次迭代情况如何 private int itera
  • 在哪里保存选项值、重要文件的路径等[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在创建一个程序 需要设置一些选项值以及图像文件的一些路径 SQLite 数据库的路径 有关各种按钮上文本的一些信息 有关要使用哪个数据库的信
  • 记录共享和映射的诊断上下文

    据我所知 其他人做了什么来解决 Commons Logging 项目 针对 NET 和 Java 不支持映射或嵌套诊断上下文这一事实 执行摘要 我们选择直接使用实现者日志框架 在我们的例子中为 log4j 长答案 您是否需要一个抽象日志框架
  • 以有效的方式从 Map 中删除多个键?

    我有一个Map
  • 在java中将字符串日期转换为美国格式

    我有下面的代码 其中日期为字符串类型 我必须将其设置为美国格式 所以下面我已经展示了它 private static final SimpleDateFormat usOutputDate new SimpleDateFormat MM d
  • 无法从资源加载图片

    So I am trying to load a image file from a resource so that when I export my application into a jar file it could be use
  • 确定序列化对象的类型

    我需要通过套接字发送消息 从用户到引擎的请求 以及从引擎到用户的响应 所以流程本质上是 serialized request Server lt network gt Client serialized response request r
  • 嵌套字段的 Comparator.comparing(...)

    假设我有一个这样的域模型 class Lecture Course course getters class Course Teacher teacher int studentSize getters class Teacher int
  • C 与 C++ 中的 JNI 调用不同?

    所以我有以下使用 Java 本机接口的 C 代码 但是我想将其转换为 C 但不知道如何转换 include
  • BadPaddingException:无效的密文

    我需要一些帮助 因为这是我第一次编写加密代码 加密代码似乎工作正常 但解密会引发错误 我得到的错误是 de flexiprovider api exceptions BadPaddingException 无效的密文 in the 解密函数
  • 如何以编程方式创建 CardView

    我正在开发一个 Android 应用程序Java Android Studio 我想在活动中创建CardView以编程方式 我想将以下属性设置为CardView layout width wrap content layout row 0
  • Android:ANT 构建失败,并显示 google-play-services-lib:“解析为没有项目的 project.properties 文件的路径”

    我正在尝试使用 ANT 构建我的应用程序 但在包含 google play services lib 库项目后 我惨遭失败 Step 1 我在 project properties 文件中设置了对库项目的引用 android library
  • Android UnityPlayerActivity 操作栏

    我正在构建一个 Android 应用程序 其中包含 Unity 3d 交互体验 我已将 Unity 项目导入 Android Studio 但启动时该 Activity 是全屏的 并且不显示 Android 操作栏 我怎样才能做到这一点 整
  • spring data jpa复合键重复键记录插入导致更新

    我有一个具有复合键的实体 我试图通过使用 spring data jpa 存储库到 mysql 数据库来持久化它 如下所示 Embeddable public class MobileVerificationKey implements S
  • 决策树和规则引擎 (Drools)

    In the application that I m working on right now I need to periodically check eligibility of tens of thousands of object

随机推荐