Arthas的使用

一、概述

可以解决问题:

  • 这个类是哪个jar包加载的?为什么会报各种类相关的Exception
  • 我改的代码为什么没有执行?
  • 遇到线上问题无法debug,难道只能通过加日志重新发布吗?
  • 线上遇到某个用户的数据处理有问题,线下无法重现
  • 是否有一个全局视角来查看系统的运行状况?
  • 有什么办法可以监控到JVM的实时运行状态?
  • 怎么养快速定位应用的热点,火焰图

运行环境要求,JDK6以上的版本,支持Tab自动补全功能,命令行的交互模式。

二、快速安装

去官网下载:下载 — Arthas 3.5.5 文档

简单命令:

  • java -jar arthas-boot.jar:启动
  • java -jar arthas-boot.jar -h:查看帮助文档,其实可以去官网查看

绿色软件,卸载的时候,直接删除即可。

三、快速入门

1、粘附一个进程

出现如下异常,增加JVM启动参数:-XX:+StartAttachListener,同时注意用户权限问题。

如果端口占用,可以使用:

java -jar arthas-boot.jar --telnet-port 端口号 --http-port -1

也可直接跟着进程ID,进行粘附。也可在浏览器上进行操作,但是端口号需要开放。 

四、基础命令

1、dashboard 仪表盘

2、thread命令查看 main class

可以使用:thread 线程ID,查看线程运行状态 :

3、jad 反编译

包含类所使用的类加载器、所在的jar包、源码。 

4、watch:查看方法在执行过程中的入参、出参

5、退出arthas

  • quit、exit:关闭当前操作界面,绘画保持
  • stop:退出回话,关闭进程

五、Arthas命令行快捷键

1、基础命令1

  • help:帮助文档                                 
  • cat:同linux下一样的意思,查看某个文件内容              
  • grep:管道命令,过滤作用
    • -n:显示行号
    • -i:忽略大小学
    • -m:最多显示多少行
    • -e:正则表达式
  • pwd:查看路径                                        
  • cls:清屏

2、基础命令2

  • session:查看当前回话信息
  • reset:还原增强的类
  • version:查看arthas版本号
  • history:查看输入的历史命令
  • quit:退出当前session,不影响其它会话
  • stop:停止当前的arthas服务
  • keymap: 显示arthas的快捷键

六、JVM相关

1、dashboard

从上至下分别是: 

  • 线程相关 
    • ID:线程ID
    • NAME:线程名字
    • GROUP:线程组
    • PRIORITY:线程优先级
    • STATE:线程状态
    • %CPU:cpu占比
    • TIME:运行时间。分钟:秒
    • INTERRUPTE:中断状态
    • DAEMON:是否是守护线程
  • 内存相关
    • Memroy:内存区域
    • used:使用的内存
    • total:总内存
    • max:最大内存
    • usage:使用百分比
    • GC:垃圾回收机制
  • 运行环境

2、thread(重要)

参数:

  • 数字:线程ID
  • n:前n个最忙的线程堆栈信息
  • b:找出当前阻塞其它线程的线程
  • i <vaue>:制定CPU占比统计采样间隔,单位为毫秒 
  • 查看某种状态的所有线程

3、jvm

4、sysprop

查看java虚拟机属性,可以修改。

5、sysenv

查看jvm环境属性

6、vmoption

查看、更新JVM诊断相关参数

7、getstatic

获取静态属性,getstatic 类名 属性名

8、ognl

执行ognl表达式,但是要学习ognl语法

1、调用静态方法 ognl '@java.lang.System@out.println("go go")'

2、获取静态字段 ognl '@demo.MathGame@random'

3、执行多行表达式,赋值给临时变量,返回一个list

ognl '#value1=@System@getProperty("java.home"),#value2=@System@getProperty("java.runtime.name"),{#value1,#value2}' 

七、class\classloader相关

1、sc

Search Class 的缩写,在jvm中检索已经加载的某个类的信息,默认查询子类

2、sm

Search method 检索方法,无法看到父类的方法

3、jad

字节码文件反编译成源代码

反编译某个方法:

4、mc

源代码编译成字节码

5、redefine

加载外部的.class文件,redefine到JVM中。

注意:redefine后的原来的类不能恢复,redefine可能失败(增加的field)。reset对redefine的类无效。如果想要重置,则需要redefine原始的字节码。会和jad/watch/trace/monitor/tt等命令冲突。执行以上命令会重置redefine的字节码重置。

限制:

  • 不允许新增field和method
  • 正在运行的函数,没有推出不能生效

 

6、dump

正在运行的类的字节码文件保存到某个目录下

7、classloader

获取类加载器的信息

八、monitor\watch\trace相关

1、monitor

监视指定时间段内一个类的方法执行情况,默认120秒坚实一次,非实时显示命令

monitor -c 5 demo.MathGame primeFactors

2、watch(因为支持ognl表达式,能够看到方法内部执行的情况)

在诊断程序过程中,使用比较多的。检测方法的执行情况,入参、返回值、异常、出参等,并且可以使用ognl查看对应变量的值。

说明:

  • watch定义了4个观察时间点,即-b方法调用前、-e方法异常后、-s方法返回后、-f方法结束后
  • 4个观察事件点-b、-e、-s默认关闭,-f默认打开,当指定观察点被打开后,在相应时间点会对观察表达式进行求值并输出
  • 这里要注意方法入参和出参的区别,参数可能在执行过程中被修改了,除了-b观察点params代表入参,其它时间点都代表出参
  • 当使用-b时,由于观察事件点在方法调用前,所以返回值或者异常都不存在 

案例:

1、监控方法出参和返回值,属性遍历深度为2

watch demo.MathGame primeFactors "{params,returnObj}" -x 2

2、观察方法的入参,因为观察点是执行前,所以只能看到入参,无法看到返回值

watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b 

3、观察调用方法的对象属性,查看方法执行前后,当前对象中的属性,可以使用traget关键字,表示当前对象

watch demo.MathGame primeFactors "traget" -x 2 -b

4、查看对象的属性

watch demo.MathGame primeFactors "target.illegalArgumentCount" -x 2

 5、方法调用前后,参数的不同,执行2次

watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2 

6、查看第一个参数小于0的情况

watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"  -x 2 -b

3、trace

对于方法内部调用路径进行追踪,并输出每个节点上的耗时。

1、查看某个方法的运行情况,只补货2次运行结果

trace demo.MathGame run -n 2

 2、跳过jdk执行的方法

trace --skipJDKMethod false demo.MathGame run -n 2

3、对耗时进行筛选

 trace demo.MathGame run -n 2 '#cost >.5'

4、stack

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

1、查看方法的输出路径,2次

stack demo.MathGame primeFactors -n 2

2、条件表达式,第0个参数小于0 

stack demo.MathGame primeFactors 'params[0]<0' -n 2

3、耗时

stack demo.MathGame primeFactors 'params[0]<0 and #cost>0.5' -n 2

5、tt

time-tunnel 时间隧道,记录指定方法每次调用的入参和返回信息,并对这些不同的时间调用的信息进行观测。watch需要会ognl表达式,所以有些时候不那么好用。

说明:

  • 支持条件表达式
  • 解决方法重载
    • tt -t *Test print params.length==1,指定参数个数
    • tt -t *Test print params[1] instanceof Interger 指定参数类型
  • 指定参数值
    • tt -t *Test print params[0].mobile="13103000103"

1、调用某个方法的时间隧道 

tt -t demo.MathGame primeFactors

2、 检索时间片段,显示之前记录的全部时间隧道

tt -l

tt -s 'method.name=="xxx"'

tt -i 1010:查看索引为某次的调用

tt -i 1010 -p --replay-times 3 --replay-interval 2:重新调用

5、火焰图 profiler

生成火焰图,使用步骤:

  • 启动:profiler start,每隔时间多JVM进行采集
  • 获取采集样本:profiler getSamples
  • 查看当前获取状态:profiler stastus
  • 停止:profiler stop

6、option

arthas全局选项配置

九、实践:哪个Controller处理了请求

需求:

1、确定哪个controller处理了请求?

trace org.springframework.web.servlet.DispatcherServlet *

jad org.springframework.web.servlet.DispatcherServlet  查看到 方法getHandler

以上其实如果熟悉spring mvc 的源码,直接就能定位到。

watch org.springframework.web.servlet.DispatcherServlet getHandler '{params,returnObj}' -x 2

2、每个请求调用的参数和返回值是多少?

经过以上操作,就能看到这个请求具体调用应用里面的代码是哪个了。可以看到参数为空,返回值也为空,中间是target调用方法的对象。

十、总结

简单把arthas工具学习了一下。感谢黑马的老师的讲解。

  • JVM的排查:可以看到thread的运行情况,对于线程的排查理论上可以替代jstack,但是如果需要优化,则还是需要使用工具对dump文件进行分析。没看官网,不清楚arthas是否有这类的功能,但是应该没有一些图形化界面好用
  • GC的排查:理论上应该没有gceasy一类的工具好用,是否有功能不确定
  • 请求流程的排查:只能说牛逼,但是需要熟悉OGNL表达式,能够实时的查看方法的执行情况、流程、耗时等,并且能够对代码进行反编译和增强。

最后还是需要在实际环境中多用用,还有需要书序OGNL。这样能更方便的写出追踪语句。

idea插件 arthas-idea-plugin/README.md at master · WangJi92/arthas-idea-plugin · GitHub

官方的使用案例:https://github.com/alibaba/arthas/issues?page=1&q=+is%3Aissue+label%3Auser-case&utf8=%E2%9C%93icon-default.png?t=M0H8https://github.com/alibaba/arthas/issues?page=1&q=+is%3Aissue+label%3Auser-case&utf8=%E2%9C%93

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值