https://alibaba.github.io/arthas/install-detail.html
应用实践
https://excel-bat.github.io/2019/03/13/引发线程cpu占用率持续飙升的根因分析/
https://github.com/alibaba/arthas/issues/482
https://github.com/alibaba/arthas/issues/429
1.启动:
java -jar arthas-boot.jar
选择应用java进程:
1
2.查看dashboar
输入dashboard,按回车/enter,会展示当前进程的信息,按ctrl+c可以中断执行。
3.查看dashboard输出
$ dashboard
ID NAME GROUP PRIORI STATE %CPU TIME INTERRU DAEMON
17 pool-2-thread-1 system 5 WAITIN 67 0:0 false false
27 Timer-for-arthas-dashb system 10 RUNNAB 32 0:0 false true
11 AsyncAppender-Worker-a system 9 WAITIN 0 0:0 false true
9 Attach Listener system 9 RUNNAB 0 0:0 false true
3 Finalizer system 8 WAITIN 0 0:0 false true
2 Reference Handler system 10 WAITIN 0 0:0 false true
4 Signal Dispatcher system 9 RUNNAB 0 0:0 false true
26 as-command-execute-dae system 10 TIMED_ 0 0:0 false true
13 job-timeout system 9 TIMED_ 0 0:0 false true
1 main main 5 TIMED_ 0 0:0 false false
14 nioEventLoopGroup-2-1 system 10 RUNNAB 0 0:0 false false
18 nioEventLoopGroup-2-2 system 10 RUNNAB 0 0:0 false false
23 nioEventLoopGroup-2-3 system 10 RUNNAB 0 0:0 false false
15 nioEventLoopGroup-3-1 system 10 RUNNAB 0 0:0 false false
Memory used total max usage GC
heap 32M 155M 1820M 1.77% gc.ps_scavenge.count 4
ps_eden_space 14M 65M 672M 2.21% gc.ps_scavenge.time(m 166
ps_survivor_space 4M 5M 5M s)
ps_old_gen 12M 85M 1365M 0.91% gc.ps_marksweep.count 0
nonheap 20M 23M -1 gc.ps_marksweep.time( 0
code_cache 3M 5M 240M 1.32% ms)
Runtime
os.name Mac OS X
os.version 10.13.4
java.version 1.8.0_162
java.home /Library/Java/JavaVir
tualMachines/jdk1.8.0
_162.jdk/Contents/Hom
e/jre
4.根据dashboard-id选择进程
通过thread命令来获取到arthas-demo进程的Main Class
$ thread 1 | grep 'main('
at demo.MathGame.main(MathGame.java:17)
5.退出
退出arthas
如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
如果想完全退出arthas,可以执行shutdown命令。
6.命令集合
**基础命令**
help——查看命令帮助信息
cat——打印文件内容,和linux里的cat命令类似
pwd——返回当前的工作目录,和linux命令类似
cls——清空当前屏幕区域
session——查看当前会话的信息
reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
version——输出当前目标 Java 进程所加载的 Arthas 版本号
history——打印命令历史
quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
shutdown——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
keymap——Arthas快捷键列表及自定义快捷键
**jvm相关**
dashboard——当前系统的实时数据面板
thread——查看当前 JVM 的线程堆栈信息
jvm——查看当前 JVM 的信息
sysprop——查看和修改JVM的系统属性
sysenv——查看JVM的环境变量
getstatic——查看类的静态属性
New! ognl——执行ognl表达式
class/classloader相关
sc——查看JVM已加载的类信息
sm——查看已加载类的方法信息
jad——反编译指定已加载类的源码
mc——内存编绎器,内存编绎.java文件为.class文件
redefine——加载外部的.class文件,redefine到JVM里
dump——dump 已加载类的 byte code 到特定目录
classloader——查看classloader的继承树,urls,类加载信息,使用classloader去getResource
**monitor/watch/trace相关**
请注意,这些命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上、预发使用时,请尽量明确需要观测的类、方法以及条件,诊断结束要执行 shutdown 或将增强过的类执行 reset 命令。
monitor——方法执行监控
watch——方法执行数据观测
trace——方法内部调用路径,并输出方法路径上的每个节点上耗时
stack——输出当前方法被调用的调用路径
tt——方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
options
options——查看或设置Arthas全局开关
**管道**
Arthas支持使用管道对上述命令的结果进行进一步的处理,如sm java.lang.String * | grep 'index'
grep——搜索满足条件的结果
plaintext——将命令的结果去除ANSI颜色
wc——按行统计输出结果
SC命令
sc class类名.*
打印api包下所有的类
$ sc com.kxtx.xks.batchbill.api.*
com.kxtx.xks.batchbill.api.BatchBillApi
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848$$FastClassBySpringCGLIB$$3eba3c87
com.kxtx.xks.batchbill.api.BatchBillApi$$FastClassBySpringCGLIB$$1f34c538
com.kxtx.xks.batchbill.api.BatchBillRepairApi
com.kxtx.xks.batchbill.api.BatchBillRepairApi$$EnhancerBySpringCGLIB$$4ec1a841
com.kxtx.xks.batchbill.api.DeployTestController
com.kxtx.xks.batchbill.api.ReportApi
com.kxtx.xks.batchbill.api.ReportApi$$EnhancerBySpringCGLIB$$88f05835
Affect(row-cnt:9) cost in 17 ms.
打印类的详细信息
$ sc -d com.kxtx.xks.batchbill.api.BatchBillApi
class-info com.kxtx.xks.batchbill.api.BatchBillApi
code-source /D:/xk/xk_project/730/service-xks-batchbill/xks-batchbill-business/target/classes/
name com.kxtx.xks.batchbill.api.BatchBillApi
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name BatchBillApi
modifier public
annotation org.springframework.web.bind.annotation.RestController,org.springframework.web.bind.annotation.RequestMapping,io.swagger.annotations.Api
interfaces
super-class +-java.lang.Object
class-loader +-sun.misc.Launcher$AppClassLoader@18b4aac2
+-sun.misc.Launcher$ExtClassLoader@3b2da18f
classLoaderHash 18b4aac2
class-info com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848
code-source /D:/xk/xk_project/730/service-xks-batchbill/xks-batchbill-business/target/classes/
name com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name BatchBillApi$$EnhancerBySpringCGLIB$$42686848
modifier public
annotation
interfaces org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.cglib.proxy.Factory
super-class +-com.kxtx.xks.batchbill.api.BatchBillApi
+-java.lang.Object
class-loader +-sun.misc.Launcher$AppClassLoader@18b4aac2
+-sun.misc.Launcher$ExtClassLoader@3b2da18f
classLoaderHash 18b4aac2
Affect(row-cnt:2) cost in 30 ms.
打印类的字段信息
$ sc -d -f com.kxtx.xks.batchbill.api.BatchBillApi
class-info com.kxtx.xks.batchbill.api.BatchBillApi
code-source /D:/xk/xk_project/730/service-xks-batchbill/xks-batchbill-business/target/classes/
name com.kxtx.xks.batchbill.api.BatchBillApi
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name BatchBillApi
modifier public
annotation org.springframework.web.bind.annotation.RestController,org.springframework.web.bind.annotation.RequestMapping,io.swagger.annotations.Api
interfaces
super-class +-java.lang.Object
class-loader +-sun.misc.Launcher$AppClassLoader@18b4aac2
+-sun.misc.Launcher$ExtClassLoader@3b2da18f
classLoaderHash 18b4aac2
fields modifierfinal,private,static
type org.slf4j.Logger
name log
value Logger[com.kxtx.xks.batchbill.api.BatchBillApi]
modifier
type com.kxtx.xks.batchbill.service.IBatchBizBillService
name batchBizBillService
annotationorg.springframework.beans.factory.annotation.Autowired
modifier
type com.kxtx.xks.batchbill.service.IBatchChargeDetailServi
ce
name batchChargeDetailService
annotationorg.springframework.beans.factory.annotation.Autowired
modifier
type com.kxtx.xks.batchbill.service.IStateTraceService
name stateTraceService
annotationorg.springframework.beans.factory.annotation.Autowired
modifier
type com.kxtx.xks.batchbill.service.IBizBillService
name bizBillService
annotationorg.springframework.beans.factory.annotation.Autowired
class-info com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848
code-source /D:/xk/xk_project/730/service-xks-batchbill/xks-batchbill-business/target/classes/
name com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name BatchBillApi$$EnhancerBySpringCGLIB$$42686848
modifier public
annotation
interfaces org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.cglib.proxy.Factory
super-class +-com.kxtx.xks.batchbill.api.BatchBillApi
+-java.lang.Object
class-loader +-sun.misc.Launcher$AppClassLoader@18b4aac2
+-sun.misc.Launcher$ExtClassLoader@3b2da18f
classLoaderHash 18b4aac2
fields modifierprivate
type boolean
name CGLIB$BOUND
modifierpublic,static
type java.lang.Object
name CGLIB$FACTORY_DATA
value org.springframework.cglib.proxy.Enhancer$EnhancerFactoryData@b8e8661
modifierfinal,private,static
type org.springframework.cglib.proxy.MethodProxy
name CGLIB$bizBillSign$3$Proxy
value org.springframework.cglib.proxy.MethodProxy@43d2c19e
modifierfinal,private,static
type java.lang.reflect.Method
name CGLIB$addBatchLoss$4$Method
value public void com.kxtx.xks.batchbill.api.BatchBillApi.addBatchLoss(com.kxtx.xks.batchbill.entity.BatchLoss)
modifierfinal,private,static
type org.springframework.cglib.proxy.MethodProxy
name CGLIB$addBatchLoss$4$Proxy
value org.springframework.cglib.proxy.MethodProxy@245b8c14
modifierfinal,private,static
type java.lang.reflect.Method
name CGLIB$queryBatchById$5$Method
value public com.kxtx.xks.batchbill.dto.BatchDTO com.kxtx.xks.batchbill.api.BatchBillApi.queryBatchById(java.lang.Long)
modifierfinal,private,static
type org.springframework.cglib.proxy.MethodProxy
name CGLIB$queryBatchById$5$Proxy
value org.springframework.cglib.proxy.MethodProxy@2d25772d
modifierfinal,private,static
type java.lang.reflect.Method
name CGLIB$cancelDelivery$6$Method
value public boolean com.kxtx.xks.batchbill.api.BatchBillApi.cancelDelivery(com.kxtx.xks.batchbill.dto.StringIdDTO)
modifierfinal,private,static
type org.springframework.cglib.proxy.MethodProxy
name CGLIB$cancelDelivery$6$Proxy
value org.springframework.cglib.proxy.MethodProxy@ddd36c0
modifierfinal,private,static
type java.lang.reflect.Method
name CGLIB$agreeAcceptBatch$7$Method
value public com.kxtx.xks.common.entity.JsonBean com.kxtx.xks.batchbill.api.BatchBillApi.agreeAcceptBatch(java.lang.String,java.lang.Long)
modifierfinal,private,static
type org.springframework.cglib.proxy.MethodProxy
name CGLIB$agreeAcceptBatch$7$Proxy
value org.springframework.cglib.proxy.MethodProxy@58d6c8d4
SM命令
“Search-Method” 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。
sm 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到。
$ sm com.kxtx.xks.batchbill.api.BatchBillApi
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848 <init>()V
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848 equals(Ljava/lang/Object;)Z
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848 toString()Ljava/lang/String;
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848 hashCode()I
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848 clone()Ljava/lang/Object;
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848 indexOf(Lorg/aopalliance/aop/Advice;)I
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848 indexOf(Lorg/springframework/aop/Advisor;)I
com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848 newInstance([Ljava/lang/Class;[Ljava/lang/Object;
Watch命令
@RequestMapping(value = "/queryBatchList", method = RequestMethod.POST)
@ApiOperation(value = "查询批次列表信息", notes = "查询批次列表信息")
public PageInfo<Batch> queryBatchList(@RequestBody QueryBatchListDTO queryBatchListDTO) {
queryBatchListDTO = queryBatchListDTO == null ? new QueryBatchListDTO() : queryBatchListDTO;
PageHelper.startPage(queryBatchListDTO.getPageNum(), queryBatchListDTO.getPageSize());
PageInfo<Batch> pageInfo = new PageInfo(batchService.selectBatchListByCondition(queryBatchListDTO));
return this.convertBatchListToBatchDTOList(pageInfo);
}
观察方法出参和返回值
$ watch com.kxtx.xks.batchbill.api.BatchBillApi queryBatchList "{params,returnObj}" -x 2
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 251 ms.
ts=2019-03-20 10:36:13; [cost=386.456844ms] result=@ArrayList[
@Object[][
@QueryBatchListDTO[com.kxtx.xks.batchbill.dto.QueryBatchListDTO@73210e00],
],
@PageInfo[
serialVersionUID=@Long[1],
pageNum=@Integer[1],
pageSize=@Integer[10],
size=@Integer[10],
startRow=@Integer[1],
endRow=@Integer[10],
total=@Long[48],
pages=@Integer[5],
list=@ArrayList[isEmpty=false;size=10],
prePage=@Integer[0],
nextPage=@Integer[2],
isFirstPage=@Boolean[true],
isLastPage=@Boolean[false],
hasPreviousPage=@Boolean[false],
hasNextPage=@Boolean[true],
navigatePages=@Integer[8],
navigatepageNums=@int[][isEmpty=false;size=5],
navigateFirstPage=@Integer[1],
navigateLastPage=@Integer[5],
],
]
ts=2019-03-20 10:36:13; [cost=438.158234ms] result=@ArrayList[
@Object[][
@QueryBatchListDTO[com.kxtx.xks.batchbill.dto.QueryBatchListDTO@73210e00],
],
@PageInfo[
serialVersionUID=@Long[1],
pageNum=@Integer[1],
pageSize=@Integer[10],
size=@Integer[10],
startRow=@Integer[1],
endRow=@Integer[10],
total=@Long[48],
pages=@Integer[5],
list=@ArrayList[isEmpty=false;size=10],
prePage=@Integer[0],
nextPage=@Integer[2],
isFirstPage=@Boolean[true],
isLastPage=@Boolean[false],
hasPreviousPage=@Boolean[false],
hasNextPage=@Boolean[true],
navigatePages=@Integer[8],
navigatepageNums=@int[][isEmpty=false;size=5],
navigateFirstPage=@Integer[1],
navigateLastPage=@Integer[5],
],
]
观察方法入参
$ watch com.kxtx.xks.batchbill.api.BatchBillApi queryBatchList "{params,returnObj}" -x 2 -b
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 115 ms.
ts=2019-03-20 10:44:13; [cost=0.00661ms] result=@ArrayList[
@Object[][
@QueryBatchListDTO[com.kxtx.xks.batchbill.dto.QueryBatchListDTO@315b31e6],
],
null,
]
ts=2019-03-20 10:44:14; [cost=0.002704ms] result=@ArrayList[
@Object[][
@QueryBatchListDTO[com.kxtx.xks.batchbill.dto.QueryBatchListDTO@315b31e6],
],
null,
]
同时观察方法调用前和方法返回后
$ watch com.kxtx.xks.batchbill.api.BatchBillApi queryBatchList "{params,target,returnObj}" -x 2 -b -s -n 2
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 112 ms.
ts=2019-03-20 10:46:41; [cost=0.003005ms] result=@ArrayList[
@Object[][
@QueryBatchListDTO[com.kxtx.xks.batchbill.dto.QueryBatchListDTO@4efbd8c2],
],
@BatchBillApi$$EnhancerBySpringCGLIB$$42686848[
CGLIB$BOUND=@Boolean[false],
CGLIB$FACTORY_DATA=@EnhancerFactoryData[org.springframework.cglib.proxy.Enhancer$EnhancerFactoryData@b8e8661],
CGLIB$THREAD_CALLBACKS=@ThreadLocal[java.lang.ThreadLocal@5497960],
CGLIB$STATIC_CALLBACKS=null,
ts=2019-03-20 10:46:41; [cost=0.003907ms] result=@ArrayList[
@Object[][
@QueryBatchListDTO[com.kxtx.xks.batchbill.dto.QueryBatchListDTO@4efbd8c2],
],
@BatchBillApi[
log=@Logger[Logger[com.kxtx.xks.batchbill.api.BatchBillApi]],
dispatchService=@DispatchServiceImpl$$EnhancerBySpringCGLIB$$e6e91c15[com.kxtx.xks.batchbill.service.impl.DispatchServiceImpl@4addfb95],
batchBizBillService=@BatchBizBillServiceImpl$$EnhancerBySpringCGLIB$$203ef3e7[com.kxtx.xks.batchbill.service.impl.BatchBizBillServiceImpl@4b477121],
batchChargeDetailService=@BatchChargeDetailServiceImpl[com.kxtx.xks.batchbill.service.impl.BatchChargeDetailServiceImpl@6fca831e],
stateTraceService=@StateTraceServiceImpl[com.kxtx.xks.batchbill.service.impl.StateTraceServiceImpl@3f4b59fd],
bizBillService=@BizBillServiceImpl[com.kxtx.xks.batchbill.service.impl.BizBillServiceImpl@56929ce],
batchService=@BatchServiceImpl[com.kxtx.xks.batchbill.service.impl.BatchServiceImpl@4a609803],
bizBillFeign=@$Proxy160[HardCodedTarget(type=BizBillFeign, name=kxtx-service-xks-bizBill, url=http://kxtx-service-xks-bizBill/kxtx-service-xks-bizbill/bizBill)],
truckerFeign=@$Proxy167[HardCodedTarget(type=TruckerFeign, name=kxtx-xks, url=http://kxtx-xks/xk/api/trucker)],
lockUtil=@LockUtil[com.kxtx.xks.util.LockUtil@452aea78],
batchLossService=@BatchLossServiceImpl[com.kxtx.xks.batchbill.service.impl.BatchLossServiceImpl@22bf4d9d],
],
null,
]
Command execution times exceed limit: 2, so command will exit. You can set it with -n option.
trace
方法内部调用路径,并输出方法路径上的每个节点上耗时
trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。
(1)trace函数
$ trace com.kxtx.xks.batchbill.api.BatchBillApi queryBatchList
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 131 ms.
`---ts=2019-03-20 10:50:15;thread_name=http-nio-20933-exec-7;id=6a;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@64b36b02
`---[28.849826ms] com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848:queryBatchList()
`---[27.055726ms] org.springframework.cglib.proxy.MethodInterceptor:intercept()
`---[26.635971ms] com.kxtx.xks.batchbill.api.BatchBillApi:queryBatchList()
+---[0.017127ms] com.kxtx.xks.batchbill.dto.QueryBatchListDTO:getPageNum()
+---[min=9.01E-4ms,max=0.003606ms,total=0.004507ms,count=2] java.lang.Integer:intValue()
+---[0.002403ms] com.kxtx.xks.batchbill.dto.QueryBatchListDTO:getPageSize()
+---[0.008413ms] com.github.pagehelper.PageHelper:startPage()
+---[23.79714ms] com.kxtx.xks.batchbill.service.IBatchService:selectBatchListByCondition()
+---[0.018329ms] com.github.pagehelper.PageInfo:<init>()
`---[2.243601ms] com.kxtx.xks.batchbill.api.BatchBillApi:convertBatchListToBatchDTOList()
(2)过滤掉jdk的函数
$ trace -j com.kxtx.xks.batchbill.api.BatchBillApi queryBatchList
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 114 ms.
`---ts=2019-03-20 10:58:51;thread_name=http-nio-20933-exec-1;id=64;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@64b36b02
`---[29.176736ms] com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848:queryBatchList()
`---[29.113938ms] org.springframework.cglib.proxy.MethodInterceptor:intercept()
`---[28.84652ms] com.kxtx.xks.batchbill.api.BatchBillApi:queryBatchList()
+---[0.006911ms] com.kxtx.xks.batchbill.dto.QueryBatchListDTO:getPageNum()
+---[0.030348ms] com.kxtx.xks.batchbill.dto.QueryBatchListDTO:getPageSize()
+---[0.637595ms] com.github.pagehelper.PageHelper:startPage()
+---[23.683263ms] com.kxtx.xks.batchbill.service.IBatchService:selectBatchListByCondition()
+---[0.011718ms] com.github.pagehelper.PageInfo:<init>()
`---[2.44732ms] com.kxtx.xks.batchbill.api.BatchBillApi:convertBatchListToBatchDTOList()
(3)据调用耗时过滤
#过滤请求处理超过20ms的请求
$ trace com.kxtx.xks.batchbill.api.BatchBillApi queryBatchList '#cost >20'
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 114 ms.
`---ts=2019-03-20 11:02:41;thread_name=http-nio-20933-exec-6;id=69;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@64b36b02
`---[24.786585ms] com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848:queryBatchList()
`---[24.536595ms] org.springframework.cglib.proxy.MethodInterceptor:intercept()
`---[23.909215ms] com.kxtx.xks.batchbill.api.BatchBillApi:queryBatchList()
+---[0.026441ms] com.kxtx.xks.batchbill.dto.QueryBatchListDTO:getPageNum()
+---[min=6.01E-4ms,max=0.002704ms,total=0.003305ms,count=2] java.lang.Integer:intValue()
+---[0.002404ms] com.kxtx.xks.batchbill.dto.QueryBatchListDTO:getPageSize()
+---[0.024338ms] com.github.pagehelper.PageHelper:startPage()
+---[21.764467ms] com.kxtx.xks.batchbill.service.IBatchService:selectBatchListByCondition()
+---[0.013822ms] com.github.pagehelper.PageInfo:<init>()
`---[1.494833ms] com.kxtx.xks.batchbill.api.BatchBillApi:convertBatchListToBatchDTOList()
`---ts=2019-03-20 11:02:46;thread_name=http-nio-20933-exec-10;id=6d;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@64b36b02
`---[20.53555ms] com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848:queryBatchList()
`---[20.457728ms] org.springframework.cglib.proxy.MethodInterceptor:intercept()
`---[20.38802ms] com.kxtx.xks.batchbill.api.BatchBillApi:queryBatchList()
+---[0.002404ms] com.kxtx.xks.batchbill.dto.QueryBatchListDTO:getPageNum()
+---[min=3.01E-4ms,max=6.01E-4ms,total=9.02E-4ms,count=2] java.lang.Integer:intValue()
+---[9.01E-4ms] com.kxtx.xks.batchbill.dto.QueryBatchListDTO:getPageSize()
+---[0.005108ms] com.github.pagehelper.PageHelper:startPage()
+---[18.672942ms] com.kxtx.xks.batchbill.service.IBatchService:selectBatchListByCondition()
+---[0.00661ms] com.github.pagehelper.PageInfo:<init>()
`---[1.508655ms] com.kxtx.xks.batchbill.api.BatchBillApi:convertBatchListToBatchDTOList()
(4)trace多个类或者多个函数
trace命令只会trace匹配到的函数里的子调用,并不会向下trace多层。因为trace是代价比较贵的,多层trace可能会导致最终要trace的类和函数非常多。
可以用正则表匹配路径上的多个类和函数,一定程度上达到多层trace的效果。
trace -E com.test.ClassA|org.test.ClassB method1|method2|method3
stack命令
输出当前方法被调用的调用路径
很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。
stack com.kxtx.xks.batchbill.api.BatchBillApi queryBatchList '#cost >20'
$ stack com.kxtx.xks.batchbill.api.BatchBillApi queryBatchList '#cost >20'
Press Q or Ctrl+C to abort.
Affect(class-cnt:2 , method-cnt:2) cost in 120 ms.
ts=2019-03-20 11:06:16;thread_name=http-nio-20933-exec-5;id=68;is_daemon=true;priority=5;TCCL=org.springframework.boot.context
@com.kxtx.xks.batchbill.api.BatchBillApi$$FastClassBySpringCGLIB$$1f34c538.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.jav
at com.kxtx.xks.intercepter.PublicRequestInterceptor.interceptor(PublicRequestInterceptor.java:27)
at sun.reflect.GeneratedMethodAccessor393.invoke(null:-1)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:62
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.kxtx.xks.batchbill.api.BatchBillApi$$EnhancerBySpringCGLIB$$42686848.queryBatchList(<generated>:-1)
at sun.reflect.GeneratedMethodAccessor392.invoke(null:-1)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocabl
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappi
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHan
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
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.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.kxtx.web.session.SessionFilter.doFilter(SessionFilter.java:17)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.kxtx.web.filter.ContextHolderResponseSetterFilter.doFilterInternal(ContextHolderResponseSetterFilter.java:30)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:111)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
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.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
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.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
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.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.cloud.sleuth.instrument.web.TraceFilter.doFilter(TraceFilter.java:169)
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.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)