Arthas线上性能诊断
简介:
Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
功能清单:
启动arthas:
-
本地启动:
本地通过cmd命令启动,首先通过命令下载arthas的jar包,再通过命令启动,attach到需要检测的java进程上。
curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar
-
k8s容器启动
-
线上docker容器内容器(需要root权限)
- 复制容器id
-
进入容器
[root@cm-nginx-node-swarm spider-patrol]# docker exec -it 628a1e1b90f3 bash bash-4.4# cd /root bash-4.4# cd arthas/ bash-4.4# java -jar arthas-boot.jar 1
arthas idea plugin 实践
该插件使用教程可以参考插件作者汪小哥的文档。
安装下载:
直接通过IDEA下载,或链接下载https://plugins.jetbrains.com/plugin/13581-arthas-idea
基础使用
在使用之前首先要获取classloader的hash 值,然后获取命令,这个是一个交互流程需要连贯性,后续只要是static 的通过static spring context的都需要有这个交互的流程,连贯的,都在同一个界面进行操作.粘贴执行,然后获取结果即可。
[arthas@20796]$ sc -d com.cloudstore.leaf.DeviceAbnormalController | grep classLoaderHash
classLoaderHash 18b4aac2 #类加载器的hashcode
[arthas@20796]$
获取static变量
粘贴命令,可以看到控制台打印出了静态变量的值。
设置static变量
ognl -x 3 '#field=@com.cloudstore.leaf.DeviceAbnormalController@class.getDeclaredField("ARTHAS_STR"),#field.setAccessible(true),#field.set(null,"设置的字符串")' -c 18b4aac2
可以看到,变量已经被修改。
注意:变量如果被final关键字修饰后,则不能通过此方法修改。
通过spring context 进行调用bean的方法、字段的内容
当获取到spring的上下文对象后,便可以通过context获得bean,进行一系列操作。
-
首先需要一个类获取Spring:
/** * @author wangrongyi * @description 提供给arthas ognl 获取context的信息 */ @Component public class ApplicationContextProvider implements ApplicationContextAware { private static ApplicationContext context; public ApplicationContext getApplicationContext() { return context; } @Override public void setApplicationContext(ApplicationContext ctx) { context = ctx; } }
-
设置一下static spring context的路径,就是上面静态ApplicationContext变量的路径
-
设置完之后就可以通过ognl命令调用方法
ognl的完整使用以及如何调用带参数的方法参考:【Arthas】命令之ognl使用姿势
ognl -x 3 '#springContext=@com.cloudstore.leaf.core.config.ApplicationContextProvider@context,#springContext.getBean("deviceAbnormalController").testArthas()' -c 18b4aac2
tips:私有方法也可以调用。Arthas可以与JRebel热部署插件结合在本地使用,不用写单测和接口就能对任意方法进行调用测试,对提升开发效率有奇效。
监控命令monitor、watch、trace、tt
-
monitor:monitor | arthas (aliyun.com)
注意:使用JRebel热部署启动后不支持watch、trace、TT等命令, 用正常模式启动就可以。
-
watch:watch | arthas (aliyun.com)
watch命令可以看到方法的入参出参以及抛出的异常
-
trace:trace | arthas (aliyun.com)
trace命令可以输出当前方法被调用的调用路径,以及方法调用的时间,可以用来分析方法的性能。
-
stack:stack | arthas (aliyun.com)
stack可以输出当前方法被调用的调用路径
-
TimeTunnel Tt 时间隧道:TimeTunnel Tt 时间隧道 · Issue #4 · WangJi92/arthas-idea-plugin · GitHub
tt 可以用来记录请求的数据,方便二次触发
jad反编译:
可以通过反编译查看部署的代码是否生效。
反编译整个类:jad --source-only com.cloudstore.leaf.DeviceAbnormalController
反编译指定方法:jad --source-only com.cloudstore.leaf.DeviceAbnormalController testArthas
arthas实现热更新(线上环境慎用!)
修改前:
修改后:
-
打包上传需要替换掉的.class文件,
-
获取该类加载器的hashcode
[arthas@20796]$ sc -d com.cloudstore.leaf.DeviceAbnormalController | grep classLoaderHash classLoaderHash 18b4aac2 #类加载器的hashcode [arthas@20796]$
-
通过redefine命令替换对应的.class文件
[arthas@20796]$ redefine -c 18b4aac2 "D:\JavaProjects\spider\spider-leaf\leaf-api\target\classes\com\cloudstore\leaf\DeviceAbnormalController.class" redefine success, size: 1, classes: com.cloudstore.leaf.DeviceAbnormalController [arthas@20796]$
注意:这种方法替换的是该java进程的二进制文件,并未修改.class 文件,所以反编译.class文件是看不到改动的。