开发者学堂课程【线上问题排查利器 Alibaba Arthas(下):Watch 命令的参数介绍】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/747/detail/13202
Watch 命令的参数介绍
内容介绍:
一、Watch 命令目标作用
二、Watch 参数说明
三、Watch 命令的演示案例
一、Watch 命令目标作用
今天来学习 watch,他在我们后期整段程序的过程中用的非常多,是用来观察指定方法的调用情况,是很多时候我们用来判断程序某处有问题的时候一个非常重要的命令。
可以用来检测一些方法的执行情况,看他的数据是否正确,而且是实时的,输出他现在的方法,这样就能看到方法的调用情况,可以看的参数有返回值、抛出异常;第三个入参,也就是输入的参数;第四个就是除参,入参参可能在方法的内部被修改,此时出来的参数和入参的参数就不一样,除了监控这四个参数之外,还有非常灵活的编写方式,也支持使用OGNL,对象图导航语音,对相应的变量进行查看。
该命令是非常灵活,可以看入参,可以看返回值,也可以看当前的对象情况,也可以指定条件,符合条件的才显示,也就是说,还可以进行过滤,甚至可以看对象当中的某一个属性,它的值是什么样的都可以,所以参数是比较多的,如下表所示
二、参数说明
watch 的参数较多,主要是因为它能在4个不同的场景观察对象
class - pattern:类名表达式匹配
method - pattern:方法名表达式匹配
express :观察表达式
condition - express :条件表达式
[b]:在方法调用之前观察 before(以下的英文为老师的猜测,辅助记忆)
[e]:在方法异常之后观察 exception
[s]: 在方法返回之后观察success
[f]:在方法结束之后(正常返回和异常返回)观察 finish
[E]: 开启正则表达式匹配,默认为通配符匹配
[x:]:指定输出结果的属性遍历深度,默认为1
这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"( params , returnOby }",只要是一个合法的 ognl 表达式,都能被正常支持。是我们迄今为止看到参数最多的一个命令
第一个是指类名表达式,这个用的比较多,第二个紧跟着的就是方法的,方法的名字,报上名之后面就是观察表达式,观察表达式往往使用OGNL,同样还可以指定第四个参数,第四个参数就是条件表达式也是使用OGNL的方式来写,这就是他的四个参数。
这四个基本参数指定以后还可以有其他的参数:
比如说b参数,b参数是指在方法调用之前观察,-e是指在方法观察一场之后,S是指在方法返回之后,f是指在方法结束之后有点像Java之中的finally,除了以上参数,也支持用正则表达式,用-E的参数;还有最后一个x只输出结果属性便利,深度默认为一,如果把深度调到更多的话,就会在某一个类里面包含的成员变量再次往下显示一级,所以这样的话,它的深度就会比较深一点,这就是她所有的一些参数,主要的就是要会写观察表达式和条件表达式,都是用ognl来写。
下面是特别说明:
(1)watch 命令定义了4个观察事件点,即 -b 方法调用前,- e 方法异常后,- s 方法返回后, f 方法结束后。有点像string里面的,切入点面向切入编程,实际上有这个前置通知,后置通知,环绕通知,异常通知还有最终通知。所以可以猜测,Arthas在编写的时候用了同样的代理模式,类似于string框架的模式,对他四个的观察点进行监视,这个虽然没有看到源码,但是可以猜测应该是这样实现的。
(2)4个观察事件点 b 、- e 、- s 默认关闭,- f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出。f默认打开,不管你有没有出现异常都能够看到结果
(3)这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 b 事件点 params 代表方法入参外,其余事件都代表方法出参
(4)当使用 b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在
三、Watch 命令的演示案例
本节课先讲六个例子当中的第一个:
1.观察 demo . MathGame 类中 primeFactors 方法出参和返回值,结果属性遍历深度为2。
出参是调用完成以后的值,遍历深度为2我们可以看的更加详细一点。
下面进行操作,清屏退出之后,重新进入,Arthas有一个特点,在半小时的时候如果没有操作的话,会自动退出来,再次进入Arthas,按1出现如下结果:
再次清除屏幕,开始写示例代码:首先我们输入Watch,此时直接回车的话会报错,因为类需要指定,所以输入demo.MathGame PrimeFactors此时不带任何参数直接回车的话也会报错,所以后面要接ognl的表达式,表达式可以用双引号也可以用单引号,中间加上一个括号,写两个参数,想要获得它的参数和返回值,参数的话用params代表一个宿主,因为我们并不知道该方法的入参是一个参数还是多个参数,所以最靠谱的方式就是用宿主。实际上的方法来看一下它的源代码,实际方法参数是只有一个整数的类型,它的返回值是一个List,List里面的每一个元素是Integer,没有执行成功的话,这边会抛异常,这就是它的源代码,也正是我们要watch的一个方法:
回到正在编写的代码,watch、类名、方法名,我们可以看到参数是一个整数,这样写的话params代表参数的一个宿主,这样写哪怕只有一个参数也可以作为宿主。接下来想知道返回值的话,后面要加一个returnObg,这样就得到了返回值,然后属性遍历的深度设置为2,用-x2这个参数,具体代码如下:
[ arthas @3670]$ watch
The argument ‘ clasS - pattern ' is required
[ arthas @3670]$ watch demo . MathGame primeFactors The argument ‘ expresS ’ is required
[ arthas @3670]$ watch demo . MathGame primeFactors "{ params , returnObj }”- x 2
然后回车开始运行,一秒钟就可以执行一次,一瞬间就执行了三次,来分析第一次为例:
组成部分前面的是时间,是指花费的时间,第一次比较长花费十毫秒,可能是缓存问题,result是指结果,结果不是指返回值,而是ognl的结果,返回的是ArrayList的结果,ArrayList里面有两个因素,第一个是参数的宿主,第二个是返回值的集合,正好和上边提到的方法所匹配,方法中第一个是整数后面返回的是List Integer,下边这个入参是一个整数的宿主,这次生成的值是142903返回的结果也是142903,正好是ArrayList里面有一个元素,142903的调用,也就是说142903分解质因数只有1和它本身。
下面来看第二次调用:
分解质因数传入的是14925,然后最终得到的结果是把它分成了3、5、5、199,也就是说3*5*5*199=14925
第三次运行可以看到是一个负数,意味着没有返回值,会抛出异常,返回值为空。
深度是2的意思是@Object[][是第一级,@ Integer [33623]是第二级。只看一级的话将看不到具体结果。以上是第一个例子的讲解。