百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

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

toyiye 2024-08-16 05:19 7 浏览 0 评论

入门步骤

安装

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官方正在举办征文活动,如果你有

  • 使用 Arthas 排查过的问题
  • 对 Arthas 进行源码解读
  • 对 Arthas 提出建议
  • 不限,其它与 Arthas 有关的内容

相关推荐

# Python 3 # Python 3字典Dictionary(1)

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中,格式如...

Python第八课:数据类型中的字典及其函数与方法

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值...

Python中字典详解(python 中字典)

字典是Python中使用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着顺序不被保留。键是不可变的。与列表一样,字典的值可以保存异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数...

Python3.9又更新了:dict内置新功能,正式版十月见面

机器之心报道参与:一鸣、JaminPython3.8的热乎劲还没过去,Python就又双叒叕要更新了。近日,3.9版本的第四个alpha版已经开源。从文档中,我们可以看到官方透露的对dic...

Python3 基本数据类型详解(python三种基本数据类型)

文章来源:加米谷大数据Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在Python中,变量就是变量,它没有类型,我们所说的"类型"是变...

一文掌握Python的字典(python字典用法大全)

字典是Python中最强大、最灵活的内置数据结构之一。它们允许存储键值对,从而实现高效的数据检索、操作和组织。本文深入探讨了字典,涵盖了它们的创建、操作和高级用法,以帮助中级Python开发...

超级完整|Python字典详解(python字典的方法或操作)

一、字典概述01字典的格式Python字典是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典的每个键值key=>value对用冒号:分割,每个对之间用逗号,...

Python3.9版本新特性:字典合并操作的详细解读

处于测试阶段的Python3.9版本中有一个新特性:我们在使用Python字典时,将能够编写出更可读、更紧凑的代码啦!Python版本你现在使用哪种版本的Python?3.7分?3.5分?还是2.7...

python 自学,字典3(一些例子)(python字典有哪些基本操作)

例子11;如何批量复制字典里的内容2;如何批量修改字典的内容3;如何批量修改字典里某些指定的内容...

Python3.9中的字典合并和更新,几乎影响了所有Python程序员

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

Python3大字典:《Python3自学速查手册.pdf》限时下载中

最近有人会想了,2022了,想学Python晚不晚,学习python有前途吗?IT行业行业薪资高,发展前景好,是很多求职群里严重的香饽饽,而要进入这个高薪行业,也不是那么轻而易举的,拿信工专业的大学生...

python学习——字典(python字典基本操作)

字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包含的元素个数不限,值...

324页清华教授撰写【Python 3 菜鸟查询手册】火了,小白入门字典

如何入门学习python...

Python3.9中的字典合并和更新,了解一下

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

python3基础之字典(python中字典的基本操作)

字典和列表一样,也是python内置的一种数据结构。字典的结构如下图:列表用中括号[]把元素包起来,而字典是用大括号{}把元素包起来,只不过字典的每一个元素都包含键和值两部分。键和值是一一对应的...

取消回复欢迎 发表评论:

请填写验证码