Arthas实践

背景

Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。

Arthas提供了非常丰富的关于调用拦截的命令,比如 trace/watch/monitor/tt 。但是很多时候我们在排查问题时,需要更多的线索,并不只是函数的参数和返回值。
比如在一个spring应用里,想获取到spring context里的其它bean。如果能随意获取到spring bean,那就可以“为所欲为”了。

下面介绍如何利用Arthas获取到spring context。

Demo: https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-arthas-spring-boot

Arthas快速开始:https://alibaba.github.io/arthas/quick-start.html

使用tt命令获取到spring context

Demo是一个spring mvc应用,请求会经过一系列的spring bean处理,那么我们可以在spring mvc的类里拦截到一些请求。

启动Demo: mvn spring-boot:run

使用Arthas Attach成功之后,执行tt命令来记录RequestMappingHandlerAdapter#invokeHandlerMethod的请求

tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod

然后访问一个网页: http://localhost:8080/

可以看到Arthas会拦截到这个调用,index是1000,并且打印出:

1$ watch com.example.demo.Test * 'params[0]@sss' 2$ tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod 3Press Ctrl+C to abort. 4Affect(class-cnt:1 , method-cnt:1) cost in 101 ms. 5 INDEX TIMESTAMP COST(ms IS-RE IS-EX OBJECT CLASS METHOD 6 ) T P 7------------------------------------------------------------------------------------------------------------------ 8 1000 2019-01-27 16:31 3.66744 true false 0x4465cf70 RequestMappingHandlerAda invokeHandlerMethod 9 :54 pter

那么怎样获取到spring context?

可以用tt命令的-i参数来指定index,并且用-w参数来执行ognl表达式来获取spring context:

1$ tt -i 1000 -w 'target.getApplicationContext()' 2@AnnotationConfigEmbeddedWebApplicationContext[ 3 reader=@AnnotatedBeanDefinitionReader[org.springframework.context.annotation.AnnotatedBeanDefinitionReader@35dc90ec], 4 scanner=@ClassPathBeanDefinitionScanner[org.springframework.context.annotation.ClassPathBeanDefinitionScanner@72078a14], 5 annotatedClasses=null, 6 basePackages=null, 7] 8Affect(row-cnt:1) cost in 7 ms.

从spring context里获取任意bean

获取到spring context之后,就可以获取到任意的bean了,比如获取到helloWorldService,并调用getHelloMessage()函数:

1$ tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()' 2@String[Hello World] 3Affect(row-cnt:1) cost in 5 ms.

更多的思路

在很多代码里都有static函数或者static holder类,顺滕摸瓜,可以获取很多其它的对象。比如在Dubbo里通过SpringExtensionFactory获取spring context:

1$ ognl '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, 2#context.getBean("userServiceImpl").findUser(1)' 3@User[ 4 id=@Integer[1], 5 name=@String[Deanna Borer], 6]

链接

原文链接

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java应用线上诊断神器

前言1、什么是Arthas?Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱(截止2020.9.19githubstar是23K)。通过Arthas我们可以在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。2、Arthas有哪些特性实时查看系统的运行状况查看函数调