阿里开源那个牛哄哄问题排查工具竟然不会用?最佳实践来了!

栏目: IT技术 · 发布时间: 3年前

内容简介:作者:汪吉https://arthas.gitee.io/install-detail.html上述命令会下载启动脚本文件 as.sh 到当前目录,执行方式:

作者:汪吉

入门步骤

安装

https://arthas.gitee.io/install-detail.html

上述命令会下载启动脚本文件 as.sh 到当前目录,执行方式:

curl -L https://alibaba.github.io/arthas/install.sh | sh

as.sh 启动 :

curl -sk https://arthas.gitee.io/arthas-boot.jar -o ~/.arthas-boot.jar  && echo "alias as.sh='java -jar ~/.arthas-boot.jar --repo-mirror aliyun --use-http'" >> ~/.bashrc && source ~/.bashrc

在线教程体验

https://alibaba.github.io/arthas/arthas-tutorials?language=cn

当然也可以自己本地体验一下~自己通过下载一个 arthas-idea-plugin的体验demo 直接本地上手

https://github.com/WangJi92/arthas-plugin-demo

全局命令说明:

-x 是展示结果属性遍历深度,默认为 1

-n 是执行的次数 ,q 退出

-c classloader 的hash值

退出 q ,关闭 stop

了解最常用的trace、watch的功能

watch和trace 是arthas 诊断中对于开发人员解决线上的问题最常用的功能!

trace

基本示例:

trace com.wangji92.arthas.plugin.demo.controller.CommonController getRandomInteger -n 5 '1==1'

https://arthas.gitee.io/trace.html

  • 性能优化~
  • 调用的这个方法,走的具体流程是咋样的!可以通过调用链看出来。
  • 有异常了可以查看异常的堆栈

高级的功能:

trace命令只会trace匹配到的函数里的子调用,并不会向下trace多层。因为trace是代价比较贵的,多层trace可能会导致最终要trace的类和函数非常多。

示例:

trace -E xxxClassA|xxxClassB method1 | method2

如:

trace -E com.wangji92.arthas.plugin.demo.controller.CommonController|com.wangji92.arthas.plugin.demo.service.ArthasTestService traceE|doTraceE -n 5 '1==1'

watch

https://arthas.gitee.io/watch.html

wathc 从字面上理解就是观察值的信息,可以查看入参、返回值、异常、可以执行表达式获取静态变量、target.xxx调用目标实施的字段、方法等等都行~只要你想得到没有做不到的~

基本示例:

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

arthas 表达式核心变量

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  
}

从watch 和 trace 中看到 后面的 ‘1==1’ 执行的是一个条件表达式 当值为true 的时候通过执行了一个ognl 表达式 ,watch 观察 params,returnObj,throwExp 入参、返回值、是否异常 这个也是一个表达式,那么这个到底是咋回事?

spring el 表达式

没有学习过ognl 使用多年的spring 一定知道他的el 表达式,el 表达式中也有一种概念叫做【Context 上下文,和表达式】 如下所示,因为有了simple这个上下文 才能解析 “booleanList[0]” 这个脚本的含义~ 这个很熟悉,很好理解,那么ognl 表达式一样不难了。

class Simple {
    public List<Boolean> booleanList = new ArrayList<Boolean>();
}

Simple simple = new Simple();

simple.booleanList.add(true);

StandardEvaluationContext simpleContext = new StandardEvaluationContext(simple);

// false is passed in here as a string. SpEL and the conversion service will
// correctly recognize that it needs to be a Boolean and convert it
parser.parseExpression("booleanList[0]").setValue(simpleContext, "false");

// b will be false
Boolean b = simple.booleanList.get(0);

ognl 表达式

arthas 也是一样的,只是使用了一个叫做ognl的脚本,核心变量就是他的上下文,可以直接获取到这些字段。watch 观察的这几个字段 params,returnObj,throwExp 也就是我们所谓的上下文的概念,观察参数、返回值、和异常的信息。

如下是arthas 源码中 表达式评估和watch 观察值执行的代码!Advice 就是一个上下文,这里还增加了一个变量 const。知道了这些那不是很简单??

com.taobao.arthas.core.advisor.ReflectAdviceListenerAdapter#isConditionMet

/**
 * 判断条件是否满足,满足的情况下需要输出结果
 * @param conditionExpress 条件表达式
 * @param advice 当前的advice对象
 * @param cost 本次执行的耗时
 * @return true 如果条件表达式满足
 */
protected boolean isConditionMet(String conditionExpress, Advice advice, double cost) throws ExpressException {
    return StringUtils.isEmpty(conditionExpress) ||
            ExpressFactory.threadLocalExpress(advice).bind(Constants.COST_VARIABLE, cost).is(conditionExpress);
}

protected Object getExpressionResult(String express, Advice advice, double cost) throws ExpressException {
    return ExpressFactory.threadLocalExpress(advice)
            .bind(Constants.COST_VARIABLE, cost).get(express);
}

表达式实践

arthas 群经常有人问重载方法如何判断,无非就是评估条件? 参数的个数、第一个参数是什么?返回值的类型等等都可以作为你评估的条件。如下的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'

条件表达式+异步任务

只有特定的场景才会有bug ,如何排查bug?

一天只出现一两次如何解决?

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

ognl 表达式

https://arthas.gitee.io/ognl.html

从上面看,ognl 在watch、trace上面无所不能啊,其实还有tt 也是 使用ognl 表达式执行逻辑的. @xxxClas@xxxStaticField 是静态变量的语法糖 ognl的,好好看一下官方的文档。

OGNL特殊用法请参考:https://github.com/alibaba/arthas/issues/71

获取静态变量

静态变量由于 一个jvm 中可能被多个classloader加载,jvm 认定为一个实例是一个classloader加载哦,所以需要知道当前静态类的hash 值(sc -d com.wangji92.arthas.plugin.demo.controller.StaticTest)可以通过这个命令获取。

ognl  -x  3 '@com.wangji92.arthas.plugin.demo.controller.StaticTest@INVOKE_STATIC_DOUBLE' -c e374b99

调用spring 方法?

watch 执行ognl 语法中获取spring context 然后进行调用bean的方法

watch -x 3 -n 1  org.springframework.web.servlet.DispatcherServlet doDispatch '@org.springframework.web.context.support.WebApplicationContextUtils@getWebApplicationContext(params[0].getServletContext()).getBean("commonController").getRandomInteger()'

ognl 执行静态的一个spring context 然后调用bean 的方法

ognl -x 3 '#springContext=@com.wangji92.arthas.plugin.demo.common.ApplicationContextProvider@context,#springContext.getBean("commonController").getRandomInteger()' -c e374b99

有没有起飞的感觉,无所不能!前提是你要掌握一些ognl的一些简单的语法!

完毕

对于线上排查问题,我感觉这几个命令够你用了,还有一些其他的反编译、火焰图、.. 时间隧道、logger 等级修改,jvm环境信息等等感觉是有频率都没有上面的高,毕竟jvm信息有专门的监控~即使没有arthas 你也可以找到更好的 工具 去分析堆栈,jvm故障。

一些特殊的用户案列值得学习思考: https://github.com/alibaba/arthas/issues?q=label%3Auser-case

完了?

啊?这么多命令 记不住啊 还有一些高级的ognl的语法凉了… 让你获取一下所有的spring的环境变量咋办?trace、watch 这两个命令我还没有体验够呢?更加高级的让我如何是好啊!好了,请看下文。

进阶

前提

前提是你对于arthas 有了大概的理解,基本上的命令都有点概念了,ognl 简单的语法能够看懂了.. 简单的条件表达式会用了。 之前我们所过arthas的命令这么多 要记住小本本少不了啊!难受想哭~ 不要急,汪小哥来给你解决问题。

目前Arthas 官方的工具还不够足够的简单,需要记住一些命令,特别是一些扩展性特别强的高级语法,比如ognl获取spring context 为所欲为,watch、trace 不够简单,需要构造一些命令工具的信息,因此只需要一个能够简单处理字符串信息的插件即可使用。当在处理线上问题的时候需要最快速、最便捷的命令,因此arthas idea 插件还是有存在的意义和价值的。

arthas idea plugin

这个插件的意义不是处理协议层面的问题,主要解决命令生成的问题,由于工程在idea 里面管理,你想想你要watch 哪个类,这个插件是知道的,帮助你更方便、更加快捷的构建命令。使用arthas idea 插件 这一点一定要理解哦!主要解决你如何构造命令的问题

阿里开源那个牛哄哄问题排查工具竟然不会用?最佳实践来了!

解决的问题

spring 环境变量优先级问题 获取静态变量 火焰图集成 logger 命令集成 反编译集成 trace -E 集成 tt 集成 ……. 基本上你能够在arths 上面看到的功能都集成到了这个上面!直接在idea 里面搜索arths idea 即可安装。

常用特殊用法问题

静态变量

可以直接获取 ognl 获取

ognl  -x  3 '@com.wangji92.arthas.plugin.demo.controller.StaticTest@INVOKE_STATIC_DOUBLE' -c e374b99

可以通过watch 获取 (光标放置在字段上)

watch com.wangji92.arthas.plugin.demo.controller.StaticTest * '{params,returnObj,throwExp,@com.wangji92.arthas.plugin.demo.controller.StaticTest@INVOKE_STATIC_DOUBLE}' -n 5 -x 3 '1==1'

一般的变量

可以通过spring context.getBean().field 获取(这个是要配置一个静态的spring context 看使用文档) tt 、watch 也是可以的哦~ 一样的原理

ognl -x 3 '#springContext=@com.wangji92.arthas.plugin.demo.common.ApplicationContextProvider@context,#springContext.getBean("staticTest").filedValue' -c e374b99

watch 获取 放置在字段上即可

watch com.wangji92.arthas.plugin.demo.controller.StaticTest * '{params,returnObj,throwExp,target.filedValue}' -n 5 -x 3 'method.initMethod(),method.constructor!=null || !@java.lang.reflect.Modifier@isStatic(method.method.getModifiers())'

选择的配置项的值springContext.getEnvironment() (这个是要配置一个静态的spring context 看使用文档)

ognl -x 3 '#springContext=@com.wangji92.arthas.plugin.demo.common.ApplicationContextProvider@context,#springContext.getEnvironment().getProperty("custom.name")' -c e374b99

获取所有的配置项的值watch 获取spring context tt 、static 也是可以的哦~ 一样的原理

watch -x 3 -n 1  org.springframework.web.servlet.DispatcherServlet doDispatch '#springContext=@org.springframework.web.context.support.WebApplicationContextUtils@getWebApplicationContext(params[0].getServletContext()),#allProperties={},#standardServletEnvironment=#propertySourceIterator=#springContext.getEnvironment(),#propertySourceIterator=#standardServletEnvironment.getPropertySources().iterator(),#propertySourceIterator.{#key=#this.getName(),#allProperties.add("                "),#allProperties.add("------------------------- name:"+#key),#this.getSource() instanceof java.util.Map ?#this.getSource().entrySet().iterator.{#key=#this.key,#allProperties.add(#key+"="+#standardServletEnvironment.getProperty(#key))}:#{}},#allProperties'

插件地址: https://plugins.jetbrains.com/plugin/13581-arthas-idea

Arthas征文地址:https://open.atatech.org/articles/175082


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ActionScript 3.0 Cookbook

ActionScript 3.0 Cookbook

Joey Lott、Darron Schall、Keith Peters / Adobe Dev Library / 2006-10-11 / GBP 28.50

Well before Ajax and Microsoft's Windows Presentation Foundation hit the scene, Macromedia offered the first method for building web pages with the responsiveness and functionality of desktop programs......一起来看看 《ActionScript 3.0 Cookbook》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试