飞道的博客

阿里开源那个牛X的问题排查工具Arthas,条件表达式+异步任务使用

479人阅读  评论(0)

问题

  • 只有特定的场景才会有bug ,如何排查bug?
  • 一天只出现一两次如何解决?

使用场景

条件表达式主要是用来过滤使用,比如某些场景只是在特定的参数才会出现,肯能会花费很多的时间去等待,这个时候可以使用条件表达式过滤 +异步任务

使用须知

在watch、trace、stack 等命令中都有条件表达式,不知道你是否用过哦!条件表达式的使用其实就是已知的信息进行逻辑运算(and or…等等),什么是已知信息,在使用arhtas的时候一定要理解他的核心参数 这些参数是我们可以利用来进行逻辑运算的核心参数,比如入参params、返回值returnObj,异常信息throwExp等等。当然除了这些参数你可能还可以通过获取静态的方法、字段获取信息来进行某些逻辑判断。比如必须是某个静态字段是这个值的情况下才ok。eg ‘@java.lang.String@serialVersionUID=-6849794470754667710L’ 这里只是随便举例子,真实场景这种使用太少了…一般都是参数 对象的xxxClass.field=‘xxx’ 条件才进行trace 、watch。
这些核心参数是在进行逻辑运算的时候通过传递给ognl执行上下文的入参信息,由此可以进行逻辑判断返回truce or false 来进行是否进行trace or watch 等等。

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 static int ACCESS_BEFORE = 1;
    private final static int ACCESS_AFTER_RETUNING = 1 << 1;
    private final static int ACCESS_AFTER_THROWING = 1 << 2;

    private final boolean isBefore;
    private final boolean isThrow;
    private final boolean isReturn;
}

参考资料

活用ognl表达式
ognl 官方

条件表达式实践

基于arthas-plugin-demo 进行演示
如下的所有的场景都必须在条件表达式成立的情况下才会执行arthas的trace 、watch 等等命令,这个可以解决问题特定场景的问题。

入参长度大于0

 watch com.wangji92.arthas.plugin.demo.controller.CommonController traceE '{params,returnObj,throwExp}' -n 5 -x 3 'params.length >0'

返回值为String 且长度大于5

watch com.wangji92.arthas.plugin.demo.controller.CommonController traceE '{params,returnObj,throwExp}' -n 5 -x 3 'returnObj instanceof java.lang.String && returnObj.length>5'

有异常

watch com.wangji92.arthas.plugin.demo.controller.CommonController traceException '{params,returnObj,throwExp}' -n 5 -x 3 'throwExp != null'

第一个参数等于’name‘

watch com.wangji92.arthas.plugin.demo.controller.CommonController traceE '{params,returnObj,throwExp}' -n 5 -x 3 'params[0]=="name"'

参数对象

ognl 支持链式调用,你可以随意的进行这种判断 比如 params[0].xxxField.xxxField
如下是官方的一个例子
All OGNL expressions are evaluated in the context of a current object, and a chain simply uses the result of the previous link in the chain as the current object for the next one. You can extend a chain as long as you like. For example, this chain:

name.toCharArray()[0].numericValue.toString()

This expression follows these steps to evaluate:

  • extracts the name property of the initial, or root, object (which the user provides to OGNL through the OGNL context);
  • calls the toCharArray() method on the resulting String;
  • extracts the first character (the one at index 0) from the resulting array;
  • gets the numericValue property from that character (the character is represented as a Character object, and the Character class has a method called getNumericValue());
  • calls toString() on the resulting Integer object. The final result of this expression is the String returned by the last toString() call.

后台执行,一天只出现一次问题排查

可以通过使用异步任务来进行排查,这里我们就使用上面的命令吧结合条件表达式+异步任务

有问题写test.txt文件里面去 & 后台异步执行

watch com.wangji92.arthas.plugin.demo.controller.CommonController traceException '{params,returnObj,throwExp}' -n 5 -x 3 'throwExp != null' > test.txt &

这个时候使用quit 命令 退出arthas控制台,让arthas 服务继续运行(stop 会停止arthas 服务),等一段时间之后就可以来查看这个文件是否有异常信息进行相关的bug诊断。

其他


转载:https://blog.csdn.net/u012881904/article/details/105603047
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场