Arthas直接执行Spring Context中的函数
简介
Arthas提供了非常丰富的关于调用拦截的命令,比如 trace
/watch
/monitor
/tt
。但是很多时候我们在排查问题时,需要更多的线索,并不只是函数的参数和返回值。
比如在一个Spring应用里,想获取到Spring context里的其它bean。如果能随意获取到Spring bean,那就可以“为所欲为”了。
下面介绍如何利用Arthas获取到Spring context。
操作步骤
Spring MVC应用,请求会经过一系列的Spring Bean处理,那么我们可以在Spring MVC的类里拦截到一些请求。
使用Arthas Attach成功之后,执行tt
命令来记录RequestMappingHandlerAdapter#invokeHandlerMethod
的请求,可以直接获取到Spring context了就
1. 使用tt命令监控Spring RequestMappingHandlerAdapter中的类
执行下列命令后,你需要做两件事
- 触发http请求,让tt命令监听到
RequestMappingHandlerAdapter
- 监控控制台,看到下方有一条记录即可。获取到下列结果的
INDEX
值,比如1000目前已经监听到了spring的bean执行了,下面来获取spring的context1
2
3
4
5
6
7
8tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
Press Q or Ctrl+C to abort.
结果:
Affect(class count: 1 , method count: 1) cost in 323 ms, listenerId: 2
INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1000 2023-04-13 10:47:54 19.308463 true false 0x39ae0bff RequestMappingHandlerAdapter invokeHandlerMethod
1001 2023-04-13 10:47:54 34.872646 true false 0x39ae0bff RequestMappingHandlerAdapter invokeHandlerMethod
2. 获取Spring的context
可以用tt
命令的-i
参数来指定index
,并且用-w
参数来执行ognl表达式来获取spring context:
1 | tt -i INDEX -w 'target.getApplicationContext()' |
3. 从Spring context里获取任意bean
获取到spring context之后,就可以获取到任意的bean了,比如获取到logBusinessOperateServiceImpl
,并调用reloadEntityFields()
函数:
1 | tt -i 1000 -w 'target.getApplicationContext().getBean("logBusinessOperateServiceImpl").reloadEntityFields()' |
如果需要传递参数的函数,则直接在调用方法的参数里直接写即可(按照方法重载的规则),例如reloadEntityFields('admin',123,3.7F)
更多的思路
在很多代码里都有static函数或者static holder类,顺滕摸瓜,可以获取很多其它的对象。比如在Dubbo里通过SpringExtensionFactory
获取spring context:
1 | ognl '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, |
帮助地址
- 原链接,GitHub issues: https://github.com/alibaba/arthas/issues/482,具体详细内容可在里面讨论。
- 官方提供Demo: https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-arthas-spring-boot
- Arthas快速开始:https://arthas.aliyun.com/doc/quick-start.html
评论
评论插件加载失败
正在加载评论插件