内容简介:冰封王座的主角, 封面上的人物:
这里 是 阿尔萨斯
的故事
冰封王座的主角, 封面上的人物:
阿里 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
查看当前线程信息,查看线程的堆栈
- 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的信息
sysprop
查看和修改当前JVM的系统属性
sysenv
查看jvm的环境变量
getstatic
查看静态变量
- getstatic class绝对路径 静态变量
- getstatic class绝对路径 静态变量 'OGNL表达式'
ognl
执行ognl 表达式
- ognl 'express' [-c classLoadHashCode] [-x value]
- -c 执行表达式的 ClassLoader 的 hashcode,默认值是SystemClassLoader
- -x 结果对象的展开层次,默认值1
class/class loader 相关命令
sc
查看JVM已加载的类信息
- sc class-partten [method-partten] [-d] [-E] [-f] [-x value]
- -d 详细信息
- -f 当前类的成员变量
- -E 开启正则(默认通配符)
sm
查看JVM已加载的方法信息
- sm class-pattern [method-pattern] [-d] [-E]
- -d 详细
- -E 开启正则
jad
反编译已加载的指定类
- jad class-pattern [method-pattern] [-c classLoadHashCode] [-E] [–source-only]
mc
内存编译
- mc xxx.java [-d value]
- -d 生成class输出到 value
redifine
替换已经加载的class文件
monitor/watch/trace相关
monitor
方法监控
- monitor class-patterm method-pattern [-c value] [-E]
- -c 统计周期为value
- -E 开启正则表达式
watch
方法执行数据监控
- 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
方法内部调用路径,并输出方法路径上的每个节点上耗时
- trace class-pattern method-pattern ['condition-express'] [-E] [-n value]
stack
输出当前方法被调用的调用路径
- stack class-pattern method-pattern ['condition-express'] [-E] [-n value]
tt
方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
ONGL
OGNL 是 Object-Graph Navigation Language 的缩写,从语言角度来说:它是一个功能强大的表达式语言,用来获取和设置 java 对象的属性 , 它旨在提供一个更高抽象度语法来对 java 对象图进行导航
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)); } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。