1.arthas基础

1.1下载启动arthas.jar(官方推荐安装方式)

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar


telnet localhost 3658 #续联  stop 是彻底停止 exit 是暂时退出

1.2 下载arthas.sh

curl -L https://alibaba.github.io/arthas/install.sh | sh

命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。

直接在shell下面执行 ./as.sh ,就会进入交互界面。

2.基础命令:

arthas命令文档:
https://arthas.aliyun.com/doc/commands.html

dashboard	查看当前系统实时数据,如线程,jvm等信息
thread	查看当前线程信息
watch	观测方法执行的数据
jvm	查看当前jvm信息
sc	查看jvm已加载的类信息
sm	查看已加载的类的信息
trace	查看方法内部调用路径
cls    清空当前屏幕区域

2.1.dashboard

输入dashboard,按回车/enter,会展示当前进程的信息,按ctrl+c可以中断执行。
在这里插入图片描述

表盘参数说明:

ID: Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
NAME: 线程名
GROUP: 线程组名
PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
STATE: 线程的状态
CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
TIME: 线程运行总时间,数据格式为分:秒
INTERRUPTED: 线程当前的中断位状态
DAEMON: 是否是daemon线程

2.2. thread

    thread pid 显示指定线程的运行堆栈

    thread -n pid 指定最忙的前N个线程并打印堆栈

    thread -b 找出当前阻塞其他线程的线程

    thread -i  指定采样时间间隔 (如:thread -n 3 -i 1000,每秒统计最忙的前三个线层)

2.3. jad反编译

输入:jad + 文件全路径

 jad  com.iot.ota.job.OTAJob  查看OTAJob反编译的源代码

2.4. watch

方法执行数据观测

让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 OGNL 表达式进行对应变量的查看。

特别说明:
watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后
4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参
当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在


-x 2:指定输出结果的属性遍历深度,默认为 1

观察方法出参和返回值:
watch demo.MathGame primeFactors "{params,returnObj}" -x 2

观察方法入参:
watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b

同时观察方法调用前和方法返回后:
watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2
参数里-n 2,表示只执行两次
这里输出结果中,第一次输出的是方法调用前的观察表达式的结果,第二次输出的是方法返回后的表达式的结果
结果的输出顺序和事件发生的先后顺序一致,和命令中 -s -b 的顺序无关

按照耗时进行过滤:
watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2

观察当前对象中的属性:
watch demo.MathGame primeFactors 'target'

然后使用target.field_name访问当前对象的某个属性
watch demo.MathGame primeFactors 'target.illegalArgumentCount'

2.5. trace

方法内部调用路径,并输出方法路径上的每个节点上耗时
注:trace 能方便的帮助你定位和发现因 RT 高而导致的性能问题缺陷,但其每次只能跟踪一级方法的调用链路。
3.3.0 版本后,可以使用动态Trace功能,不断增加新的匹配类。

[arthas@10184]$ trace  com/job/OTAJob getUpdateAppliancesInfoHandler 
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 67 ms, listenerId: 10
`---ts=2021-05-31 06:52:35;thread_name=Thread-124;id=165f3;is_daemon=false;priority=10;TCCL=org.springframework.boot.loader.LaunchedURLClassLoader@2e0fa5d3
    `---[4.589305ms] com.job.OTAJob:getUpdateAppliancesInfoHandler()
        +---[4.185527ms] com.service.ApplianOtaRecordService:getEnableUpdateApplianCodes() #52
        +---[0.015892ms] org.springframework.util.CollectionUtils:isEmpty() #53
        `---[0.137165ms] org.slf4j.Logger:info() #54

2.5.1.trace次数限制 -n 3
如果方法调用的次数很多,那么可以用-n参数指定捕捉结果的次数。比如下面的例子里,捕捉到一次调用就退出命令。

trace  com/job/OTAJob getUpdateAppliancesInfoHandler -n 2  #限制2次的调用输出

2.5.2.包含jdk的函数 --skipJDKMethod false
默认情况下,trace不会包含jdk里的函数调用,如果希望trace jdk里的函数,需要显式设置–skipJDKMethod false

[arthas@10184]$ trace --skipJDKMethod false com/job/OTAJob getUpdateAppliancesInfoHandler 
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 77 ms, listenerId: 11
`---ts=2021-05-31 06:57:36;thread_name=Thread-125;id=16628;is_daemon=false;priority=10;TCCL=org.springframework.boot.loader.LaunchedURLClassLoader@2e0fa5d3
    `---[5.36428ms] com.job.OTAJob:getUpdateAppliancesInfoHandler()
        +---[0.069739ms] java.lang.System:currentTimeMillis() #50
        +---[4.943221ms] com.service.ApplianOtaRecordService:getEnableUpdateApplianCodes() #52
        +---[0.016719ms] org.springframework.util.CollectionUtils:isEmpty() #53
        `---[0.099097ms] org.slf4j.Logger:info() #54

2.5.3.据调用耗时过滤 '#cost > 毫秒数’

 trace com/job/OTAJob getUpdateAppliancesInfoHandler '#cost>5'

2.5.4.trace多个类或者多个函数
trace命令只会trace匹配到的函数里的子调用,并不会向下trace多层。因为trace是代价比较贵的,多层trace可能会导致最终要trace的类和函数非常多。

可以用正则表匹配路径上的多个类和函数,一定程度上达到多层trace的效果。

trace -E com.test.ClassA|org.test.ClassB method1|method2|method3

2.5.5.动态trace

[arthas@10184]$ trace com/job/OTAJob getUpdateAppliancesInfoHandler '#cost>2'
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 53 ms, listenerId: 15
`---ts=2021-05-31 07:13:34;thread_name=Thread-127;id=166ab;is_daemon=false;priority=10;TCCL=org.springframework.boot.loader.LaunchedURLClassLoader@2e0fa5d3
    `---[4.018608ms] com.midea.iot.ota.job.OTAJob:getUpdateAppliancesInfoHandler()
        +---[3.609119ms] com.service.ApplianOtaRecordService:getEnableUpdateApplianCodes() #52
        +---[0.01604ms] org.springframework.util.CollectionUtils:isEmpty() #53
        `---[0.156366ms] org.slf4j.Logger:info() #54

注:动态 listenerId==15

现在想要深入子函数getEnableUpdateApplianCodes,可以打开一个新终端2,使用telnet localhost 3658连接上arthas,再trace getEnableUpdateApplianCodes时,指定listenerId。

telnet localhost 3658
trace com.service.ApplianOtaRecordService getEnableUpdateApplianCodes --listenerId 15

再次追踪链路,终端1中查看,多出了子函数getEnableUpdateApplianCodes的信息。如下:

`---ts=2021-05-31 07:31:07;thread_name=Thread-128;id=16729;is_daemon=false;priority=10;TCCL=org.springframework.boot.loader.LaunchedURLClassLoader@2e0fa5d3
    `---[4.644105ms] com..job.OTAJob:getUpdateAppliancesInfoHandler()
        +---[4.303751ms] com..service.ApplianOtaRecordService:getEnableUpdateApplianCodes() #52
        |   `---[4.216591ms] com.midea.iot.ota.service.impl.ApplianOtaRecordServiceImpl:getEnableUpdateApplianCodes()
        |       `---[4.185215ms] com.mapper.ApplianOtaRecordEntityMapper:getEnableUpdateApplians() #29
        +---[0.011063ms] org.springframework.util.CollectionUtils:isEmpty() #53
        `---[0.177292ms] org.slf4j.Logger:info() #54

2.6. stack

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


[arthas@10184]$ stack com/job/OTAJob getUpdateAppliancesInfoHandler 
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 129 ms, listenerId: 1
ts=2021-05-31 07:39:31;thread_name=Thread-131;id=16790;is_daemon=false;priority=10;TCCL=org.springframework.boot.loader.LaunchedURLClassLoader@2e0fa5d3
    @com.job.OTAJob.getUpdateAppliancesInfoHandler()
        at sun.reflect.GeneratedMethodAccessor77.invoke(null:-1)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.xxl.job.core.handler.impl.MethodJobHandler.execute(MethodJobHandler.java:31)
        at com.xxl.job.core.thread.JobThread.run(JobThread.java:163)

2.6.1 stack的过滤条件
据条件表达式来过滤
eg:第一个入参小于0,次数限制为2次

stack com/job/OTAJob getUpdateAppliancesInfoHandler  'params[0] <0' -n 2

据执行时间来过滤 时间消耗大于5毫秒

stack com/job/OTAJob getUpdateAppliancesInfoHandler  '#cost>5'

2.5. 退出arthas

如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。

telnet localhost 3658

如果想完全退出arthas,可以执行stop命令。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值