问题排查必备——Arthas 的Time Tunnel命令

36 阅读2分钟

Arthas 是开源的Java诊断工具,通过向目标虚拟机挂载agent,实现热部署,加载,调试等功能。Arthas有非常多的调用拦截等命令,很多时候我们在排查问题时,需要更多的线索,并不只是函数的参数和返回值。tt命令帮助我们获取到spring bean,从而为所欲为。

TimeTunnel的介绍

方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。

记录指定方法的每次调用环境现场:

tt -t class method

列出所有的调用记录:

tt -l

查看调用的信息:

tt -i index

重新发起一次调用

tt -i index -p

使用通道内的引用调用一次

tt -i index -w 'target.method(param)'

获取Spring Context

Spring MVC是基于MVC设计模式的开发框架,是Spring框架中用于WEB开发的一个模块,这个模块的核心是DispatcherServlet,可以将前端的请求分发到各个接口进行业务处理。DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。解析到对应的Handler后,开始由HandlerAdapter适配器处理。HandlerAdapter会根据Handler来调用真正的处理器开处理请求,并处理相应的业务逻辑。

HandlerAdapter是一个接口,真正实现的是RequestMappingHandlerAdapter,它其中有一个invokeHandlerMethod方法,用于执行目标的HandlerMethod,然后返回一个ModelAndView。每次web请求都会进入这个方法。

而RequestMappingHandlerAdapter继承了ApplicationObjectSupport,我们可以通过getApplicationContext获取到spring context。

6228661a3d8d487ff5539f9e

结合上面的只是通过和arthas的tt命令结合,我们理论上可以随时调用所有的业务方法。操作如下:

  1. 执行tt命令来记录RequestMappingHandlerAdapter invokeHandlerMethod的请求
tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
  1. 通过记录的信息,调用spring context里面保存的对象的方法
`tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'`

注意事项

    1. ThreadLocal 信息丢失 很多框架偷偷的将一些环境变量信息塞到了发起调用线程的 ThreadLocal 中,由于调用线程发生了变化,这些 ThreadLocal 线程信息无法通过 Arthas 保存,所以这些信息将会丢失。 一些常见的 CASE 比如:鹰眼的 TraceId 等。
    2. 引用的对象 需要强调的是,tt 命令是将当前环境的对象引用保存起来,但仅仅也只能保存一个引用而已。如果方法内部对入参进行了变更,或者返回的对象经过了后续的处理,那么在 tt 查看的时候将无法看到当时最准确的值。这也是为什么 watch 命令存在的意义。