转载

阿尔萨斯

这里 是 阿尔萨斯 的故事

冰封王座的主角, 封面上的人物:

阿尔萨斯

阿里 Arthas

Alibaba开源的Java诊断工具, 以命令行的方式监控跟踪线上程序运行过程,解决一些棘手的问题。

这里 是 Arthas 的官方文档, 本文简单记录一些常用的手段。

安装

  • wget https://alibaba.github.io/arthas/arthas-boot.jar
    • 备用链接 wget https://arthas.gitee.io/arthas-boot.jar
  • java -jar arthas-boot.jar
    • 备用运行姿势 java -jar arthas-boot.jar --repo-mirror aliyun --use-http

命令

基本命令

help

查看帮助 阿尔萨斯

cls

清屏

session

当前会话

reset

重置增强类, shutdown的时候也会被reset

shutdown

关闭服务端

quit

关闭当前客户端

history

历史命令

version

版本

keymap

自定义快捷键

JVM相关命令

dashboard

阿尔萨斯

thread

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

doc

  • thread 查看所有线程概览
  • thread id 查看id线程的堆栈
    • thread 1
  • thread -n value 打印最忙的前value个线程的堆栈
    • thread -n 3
  • thread -b 打印阻塞其他线程的那个线程
  • thread -i value 打印统计value ms 后的cpu占比
    • thread -i 1000

jvm

查看jvm的信息

doc

sysprop

查看和修改当前JVM的系统属性

doc

sysenv

查看jvm的环境变量

doc

getstatic

查看静态变量

doc

  • getstatic class绝对路径 静态变量
  • getstatic class绝对路径 静态变量 'OGNL表达式'

阿尔萨斯

ognl

执行ognl 表达式

doc

  • ognl 'express' [-c classLoadHashCode] [-x value]
    • -c 执行表达式的 ClassLoader 的 hashcode,默认值是SystemClassLoader
    • -x 结果对象的展开层次,默认值1

class/class loader 相关命令

sc

查看JVM已加载的类信息

doc

  • sc class-partten [method-partten] [-d] [-E] [-f] [-x value]
    • -d 详细信息
    • -f 当前类的成员变量
    • -E 开启正则(默认通配符)

sm

查看JVM已加载的方法信息

doc

  • sm class-pattern [method-pattern] [-d] [-E]
    • -d 详细
    • -E 开启正则

阿尔萨斯

jad

反编译已加载的指定类

doc

  • jad class-pattern [method-pattern] [-c classLoadHashCode] [-E] [–source-only]

mc

内存编译

doc

  • mc xxx.java [-d value]
    • -d 生成class输出到 value

redifine

替换已经加载的class文件

doc

monitor/watch/trace相关

monitor

方法监控

doc

  • monitor class-patterm method-pattern [-c value] [-E]
    • -c 统计周期为value
    • -E 开启正则表达式

watch

方法执行数据监控

doc

  • watch class-pattern method-pattern 'express' ['condition-express'] [-b] [-e] [-s] [-f] [-E] [-x value] [-n value]
    • -b 在方法调用之前观察
    • -e 在方法异常之后观察
    • -s 在方法返回之后观察
    • -f 在方法结束之后观察
    • -x 对输出结果的遍历深度
    • -n 输出几次之后自动结束

这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参

下面是核心变量

public class Advice {
 
    private final ClassLoader loader;
    private final Class<?> clazz;
    private final ArthasMethod method;
    private final Object target;
    private final Object[] params;
    private final Object returnObj;
    private final Throwable throwExp;
    private final boolean isBefore;
    private final boolean isThrow;
    private final boolean isReturn;
    
    // getter/setter  
}

trace

方法内部调用路径,并输出方法路径上的每个节点上耗时

doc

  • trace class-pattern method-pattern ['condition-express'] [-E] [-n value]

stack

输出当前方法被调用的调用路径

doc

  • stack class-pattern method-pattern ['condition-express'] [-E] [-n value]

tt

方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测

doc

ONGL

OGNL 是 Object-Graph Navigation Language 的缩写,从语言角度来说:它是一个功能强大的表达式语言,用来获取和设置 java 对象的属性 , 它旨在提供一个更高抽象度语法来对 java 对象图进行导航

  • doc
  • 官网
package ongltest;

import ognl.Ognl;
import ognl.OgnlException;

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) throws OgnlException {
        Student student = TotalFactory.genStudent1();

        Map<String, Object> map = new HashMap<>();
        map.put("student1", student);
        /**
         * <pre>
         * 1.ognl 缺省的上下文只有root和context
         * 2.#root 来显示的指定使用root还是使用context
         *
         * </pre>
         */
        // 获取student的name
        System.out.println(Ognl.getValue("name", student));
        System.out.println(Ognl.getValue("#root.name", student));

        /**
         * <pre>
         *     ognl可以写成链式的
         * </pre>
         */
        // 获取student的name的大写
        System.out.println(Ognl.getValue("name.toUpperCase()", student));

        /**
         * <pre>
         *     ognl 可以显示的指定使用context or root
         * </pre>
         */
        // 设置一个上下文
        System.out.println(Ognl.getValue("#context.student1.name", map, student));
        System.out.println(Ognl.getValue("#root.name", map, student));

        /**
         * <pre>
         *     context如果被添加之后, context里面的map都会变成跟root一个级别
         * </pre>
         */
        System.out.println(Ognl.getValue("#student1.name", map, student));

        /**
         * <pre>
         * 常量
         * 属性的引用 例如:user.name
         * 变量的引用 例如:#name
         * 静态变量的访问 使用 @class@field
         * 静态方法的调用 使用 @class@method(args), 如果没有指定 class 那么默认就使用 java.lang.Math.
         * 构造函数的调用 例如:new java.util.ArrayList();
         * </pre>
         */
        System.out.println(Ognl.getValue("@ongltest.Student@CODE", student));
        System.out.println(Ognl.getValue("@java.lang.Math@abs(-1)", student));

        /**
         * <pre>
         *  ognl可以set值
         * </pre>
         */
        Ognl.setValue("name", student, "gc2");
        System.out.println(Ognl.getValue("name", student));

        /**
         * <pre>
         *     ognl 还可以使用表达式判断
         * </pre>
         */
        System.out.println(Ognl.getValue("#root.phone.{? #this.equals('12345')}", student));
        System.out.println(Ognl.getValue("#root.phone.{? #this.equals('12345')}[0]", student));
        System.out.println(Ognl.getValue("#root.{ #this.phone.size > 1 ? #this.phone[1] : #this.phone[0] }", student));
    }
}
原文  http://int32.me/blog/2019/06/23/archas/
正文到此结束
Loading...