牛掰~ 通过Arthas定位,解决了spring-boot中内嵌tomcat的Bug问题

本文记录了一次通过Arthas工具解决Spring Boot应用内嵌Tomcat性能问题的过程。在使用Arthas进行trace和stack命令分析后,发现在加载jar包资源时,特别是`META-INF/`和`META-INF/MANIFEST.MF`时存在耗时。进一步深入源码和使用watch命令监控,发现问题与Swagger UI相关,移除Swagger相关jar包后问题得到解决。
摘要由CSDN通过智能技术生成

| ±–[2.054361ms] org.springframework.web.servlet.DispatcherServlet:getHandler() #964

| | `—[1.961963ms] org.springframework.web.servlet.DispatcherServlet:getHandler()

| | ±–[0.02051ms] java.util.List:iterator() #1183

| | ±–[min=0.003805ms,max=0.009641ms,total=0.013446ms,count=2] java.util.Iterator:hasNext() #1183

| | ±–[min=0.003181ms,max=0.009751ms,total=0.012932ms,count=2] java.util.Iterator:next() #1183

| | ±–[min=0.005841ms,max=0.015308ms,total=0.021149ms,count=2] org.apache.commons.logging.Log:isTraceEnabled() #1184

| | `—[min=0.474739ms,max=1.19145ms,total=1.666189ms,count=2] org.springframework.web.servlet.HandlerMapping:getHandler() #1188

| ±–[0.013071ms] org.springframework.web.servlet.HandlerExecutionChain:getHandler() #971

| ±–[0.372236ms] org.springframework.web.servlet.DispatcherServlet:getHandlerAdapter() #971

| | `—[0.280073ms] org.springframework.web.servlet.DispatcherServlet:getHandlerAdapter()

| | ±–[0.004804ms] java.util.List:iterator() #1224

| | ±–[0.003668ms] java.util.Iterator:hasNext() #1224

| | ±–[0.003038ms] java.util.Iterator:next() #1224

| | ±–[0.006451ms] org.apache.commons.logging.Log:isTraceEnabled() #1225

| | `—[0.012683ms] org.springframework.web.servlet.HandlerAdapter:supports() #1228

| ±–[0.012848ms] javax.servlet.http.HttpServletRequest:getMethod() #974

| ±–[0.013132ms] java.lang.String:equals() #975

| ±–[0.003025ms] org.springframework.web.servlet.HandlerExecutionChain:getHandler() #977

| ±–[0.008095ms] org.springframework.web.servlet.HandlerAdapter:getLastModified() #977

| ±–[0.006596ms] org.apache.commons.logging.Log:isDebugEnabled() #978

| ±–[0.018024ms] org.springframework.web.context.request.ServletWebRequest:() #981

| ±–[0.017869ms] org.springframework.web.context.request.ServletWebRequest:checkNotModified() #981

| ±–[0.038542ms] org.springframework.web.servlet.HandlerExecutionChain:applyPreHandle() #986

| ±–[0.00431ms] org.springframework.web.servlet.HandlerExecutionChain:getHandler() #991

| ±–[4.248493ms] org.springframework.web.servlet.HandlerAdapter:handle() #991

| ±–[0.014805ms] org.springframework.web.context.request.async.WebAsyncManager:isConcurrentHandlingStarted() #993

| ±–[1.444994ms] org.springframework.web.servlet.DispatcherServlet:applyDefaultViewName() #997

| | `—[0.067631ms] org.springframework.web.servlet.DispatcherServlet:applyDefaultViewName()

| ±–[0.012027ms] org.springframework.web.servlet.HandlerExecutionChain:applyPostHandle() #998

| ±–[0.373997ms] org.springframework.web.servlet.DispatcherServlet:processDispatchResult() #1008

| | `—[0.197004ms] org.springframework.web.servlet.DispatcherServlet:processDispatchResult()

| | ±–[0.007074ms] org.apache.commons.logging.Log:isDebugEnabled() #1075

| | ±–[0.005467ms] org.springframework.web.context.request.async.WebAsyncUtils:getAsyncManager() #1081

| | ±–[0.004054ms] org.springframework.web.context.request.async.WebAsyncManager:isConcurrentHandlingStarted() #1081

| | `—[0.011988ms] org.springframework.web.servlet.HandlerExecutionChain:triggerAfterCompletion() #1087

| `—[0.004015ms] org.springframework.web.context.request.async.WebAsyncManager:isConcurrentHandlingStarted() #1018

±–[0.005055ms] org.springframework.web.context.request.async.WebAsyncUtils:getAsyncManager() #928

`—[0.003422ms] org.springframework.web.context.request.async.WebAsyncManager:isConcurrentHandlingStarted() #928

[jboss@VM_10_91_centos tmp]$ curl -w “@curl-time.txt” http://127.0.0.1:7744/send

success

http: 200

dns: 0.001s

redirect: 0.000s

time_connect: 0.001s

time_appconnect: 0.000s

time_pretransfer: 0.001s

time_starttransfer: 0.115s

size_download: 7bytes

speed_download: 60.000B/s


time_total: 0.115s

本次调用,调用端时间花费115ms,但是从arthas trace上看,spring mvc只消耗了18ms,那么剩下的97ms去哪了呢?

本地测试后已经可以排除spring mvc的问题了,最后也是唯一可能出问题的点就是tomcat

可是本人并不熟悉tomcat中的源码,就连请求入口都不清楚,tomcat里需要trace的类都不好找。。。

不过没关系,有神器Arthas,可以通过stack命令来反向查找调用路径,以

org.springframework.web.servlet.DispatcherServlet作为参数:

stack 输出当前方法被调用的调用路径

很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。

[arthas@24851]$ stack org.springframework.web.servlet.DispatcherServlet *

Press Q or Ctrl+C to abort.

Affect(class-cnt:1 , method-cnt:44) cost in 495 ms.

ts=2019-09-14 21:15:19;thread_name=http-nio-7744-exec-5;id=14;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@7c136917

@org.springframework.web.servlet.FrameworkServlet.processRequest()

at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)

at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)

at org.springframework.web.filter.RequestContextFilter.doF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值