Arthas 是Alibaba开源的Java诊断工具。安装在系统所在服务器。可以帮助开发人员或者运维人员查找问题,分析性能,bug追踪。
Arthas运行原理
解决问题:
提供性能看板,包括线程、cpu、内存等信息,并且会定时的刷新。
根据各种条件查看线程快照。比如找出cpu占用率最高的n个线程等
输出jvm的各种信息,如gc算法、jdk版本、ClassPath等
查看/设置sysprop和sysenv
查看某个类的静态属性,也可以通过ognl语法执行一些语句
查看已加载的类的详细信息,比如这个类从哪个jar包加载的。也可以查看类的方法的信息
dump某个类的字节码到指定目录
直接反编译指定的类
查看类加载器的一些信息
可以让jvm重新加载某个类
监控方法的执行,同时可以获取到执行的入参、出参以及抛出的异常
追踪方法执行的调用栈,以及各个方法的调用时间
场景:
1)调用接口时,接口返回异常信息,如果该异常信息没有清晰的定位到代码,那么我们通常只能依靠大脑回忆代码,来估计错误发生地了,如果无法估计,一般情况下就会进入测试环境,模拟复现,如果无法复现 _。
2)这个查询,耗时20s,我们想要分析一下到底是哪些代码导致的。但是该方法内部又穿插调用了其它业务功能方法,难道手写System.currentTimeMillis()自己做减运算,还是guava的StopWatch亦或是commons的StopWatch?这几种方式需要我们手动嵌入代码,容易遗漏、费力还费时。
下载地址:
wget https://alibaba.github.io/arthas/arthas-boot.jar
启动:
java -jar arthas-boot.jar
退出arthas
quit —— 退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
shutdown —— 关闭 Arthas 服务端,所有 Arthas 客户端全部退出 & 重置所有增强过的类,就不用单独调用reset
windows
进入目录,cmd回车
java -jar arthas-boot.jar
确认线程
jps
jinfo 3260
arthas The telnet port 3658 is used by process
解决办法:
根据错误提示找到对应的进程, 如上面日志提示进程是19264, 则启动arthas之后,重新选择这个进程attach,成功之后执行stop命令,然后再正常退出arthas即可,再次启动attach其它进程即可。
Arthas命令列表
1)输入dashboard,回车,仪表盘显示当前进程相关信息。
2)查看具体线程信息使用 [thread 线程id]
thread -i 5000
前三行
thread -i 5000 -n 3
3)查看类里某个方法的返回值和入参
命令+类完全限定名+监测方法+表达式
watch com.adou.devcenter.controller.requirement.FunctionController query"{params,returnObj}"
表达式核心变量列表:
loader 本次调用类所在的 ClassLoader
clazz 本次调用类的 Class 引用
method 本次调用方法反射引用
target 本次调用类的实例params 本次调用参数列表,这是一个数组,如果方法是无参方法则为空数组
returnObj 本次调用返回的对象。当且仅当 isReturntrue 成立时候有效,表明方法调用是以正常返回的方式结束。如果当前方法无返回值 void,则值为 null
throwExp 本次调用抛出的异常。当且仅当 isThrowtrue 成立时有效,表明方法调用是以抛出异常的方式结束。
isBefore 辅助判断标记,当前的通知节点有可能是在方法一开始就通知,此时 isBeforetrue 成立,同时 isThrowfalse 和 isReturn==false,因为在方法刚开始时,还无法确定方法调用将会如何结束。
isThrow 辅助判断标记,当前的方法调用以抛异常的形式结束。
isReturn 辅助判断标记,当前的方法调用以正常返回的形式结束。
4)方法调用路径、耗时解析
方法内部调用路径,并输出方法路径上的每个节点上耗时
trace com.adou.devcenter.service.requirement.FunctionService query
或者
安装arthas-ideal-plus插件
5)时空隧道
方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
tt -t com.adou.devcenter.controller.requirement.FunctionController
-t 代表记录下每次方法执行情况
6)查看JVM已加载的类信息
sc -d com.adou.devcenter.controller.requirement.FunctionController
-d 输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。
如果一个类被多个ClassLoader所加载,则会出现多次
为什么调用一次接口会出现两条记录?
因为SpringMVC初始化时会通过cglib生成FunctionController 的代理对象,DispatchServlet真正使用的却是这个代理对象,在代理对象里调用FunctionController 的query方法,所以当我们执行tt watch命令时,会出现两条。
顺序如下:
FunctionController EnhancerBySpringCGLIB eefa08b -> FunctionController -> query()
往上查找调用者,并做展示,我们会发现第一条的执行时间略小于第二条的执行时间,基本符合上述我们的推断。
java -jar arthas-boot.jar --target-ip 192.168.168.67
在局域网内,其它机器可访问 http://192.168.168.67:8563
默认情况下,arthas只listen 127.0.0.1,所以如果想从远程连接,则可以使用 --target-ip参数指定listen的IP,更多参考-h的帮助说明。 注意会有安全风险,考虑tunnel server的方案。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)