背景
Arthas是阿里巴巴开源的Java诊断利器,深受开发者喜爱。
之前分享了Arthas怎样排查 404/401 的问题: http://hengyunabc.github.io/arthas-spring-boot-404-401/
我们可以快速定位一个请求是被哪些Filter
拦截的,或者请求最终是由哪些Servlet
处理的。
但有时,我们想知道一个请求是被哪个Spring MVC Controller处理的。如果翻代码的话,会比较难找,并且不一定准确。
通过Arthas可以精确定位是哪个Controller
处理请求。
Demo
还是以这个demo为例: https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-404-401
启动之后,访问: http://localhost:8080/user/1 ,会返回一个user对象。那么这个请求是被哪个Controller
处理的呢?
trace定位DispatcherServlet
我们先试下跟踪Servlet
:
1 | trace javax.servlet.Servlet * |
从trace的结果可以看出来,请求最终是被DispatcherServlet#doDispatch()
处理了,但是没有办法知道是哪个Controller
处理。
1 | `---[27.453122ms] org.springframework.web.servlet.DispatcherServlet:doDispatch() |
watch定位handler
trace结果里把调用的行号打印出来了,我们可以直接在IDE里查看代码(也可以用jad命令反编译):
1 | // org.springframework.web.servlet.DispatcherServlet |
- 仔细看代码,可以发现
mappedHandler = getHandler(processedRequest);
得到了处理请求的handler
下面用watch
命令来获取getHandler
函数的返回结果。
watch
之后,再次访问 http://localhost:8080/user/1
1 | $ watch org.springframework.web.servlet.DispatcherServlet getHandler returnObj |
可以看到处理请求的handler是 com.example.demo.arthas.user.UserController.findUserById
。
总结
- Spring MVC的请求是在
DispatcherServlet
分发,查找到对应的mappedHandler
来处理 - 使用Arthas时,灵活结合代码,可以快速精确定位问题