您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
JAVA开发、测试问题排查利器-Arthas
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
JAVA开发、测试问题排查利器-Arthas
自猿其说Tech
2021-07-06
IP归属:未知
68160浏览
测试
计算机编程
### 1 前言 开发人员在开发过程中经常会遇到的问题: - 一个服务特别慢,要怎么排查是哪慢呢? - 当前运行的程序占用CPU特别高,是什么在消耗CPU? - 测试时出现问题,没有输出日志,这个方法的出入参是啥? 遇到以上问题,好多开发人员都是通过加日志的方式,但改完代码后还要再次部署,而且排查问题的日志加的太多,经常会忘了清理,容易对测试环境和线上产生污染,造成大量的日志输出。某些访问量大的服务甚至会对应用的性能生产影响。 下面就给大家介绍一款开源的工具-Arthas,可以使研发和测试人员在程序运行时监控方法的调用栈、出入参,JVM的运行状态. ### 2 快速安装 #### 2.1 mac\linux: ```bash curl -L https://arthas.aliyun.com/install.sh | sh ``` 执行完后会在当前目录下生成as.sh脚本。 执行as.sh就可以启动 ```bash ./as.sh ``` 启动后会列出当前服务器上的所有JAVA进程,选择我们要监听的服务(本机上我的Tomcat进程是4)4回车后开始监听。 ![](//img1.jcloudcs.com/developer.jdcloud.com/b966de4a-6791-43b9-bcd9-8d24ede8c24720210706134524.png) #### 2.2 Windows: 打开下面的链接后下载页面最低下的 arthas-bin.zip。解压完后运行as.bat https://github.com/alibaba/arthas/releases/tag/arthas-all-3.5.1 ### 3 开始使用 #### 3.1 怎么分析服务慢在哪? 以京喜的用户查询服务为例,我们使用trace命令监听用户查询方法 ```bash trace com.zhongyouex.org.provider.api.impl.UserInfoBusinessApiImpl queryWBLoginInfo ``` 执行完上面的命令后,会开始监听com.zhongyouex.org.provider.api.impl.UserInfoBusinessApiImpl这个类中的queryWBLoginInfo方法。当我们调用这个方法时会输出这个服务下的所有方法的耗时 ![](//img1.jcloudcs.com/developer.jdcloud.com/24ca2319-d2b5-4198-94f1-cd734f02f61020210706135214.png) 我们可以通过以上的输出对耗时较大的方法进行优化。 另外该命令还有一些参数可供我们自行选择,如只显示调用时长超过500ms的记录 ```bash trace com.zhongyouex.org.provider.api.impl.UserInfoBusinessApiImpl queryWBLoginInfo '#cost>500' ``` #### 3.2 怎么查询问题方法的入参和出参 测试环境下如果我们调用某方法发生异常时,我们一般先观察下调用方法的入参和出参是什么?再进行判断,但如果代码中没有进行日志输出要怎么办呢?只能重新更新代码再发布吗? Arthas提供了一个watch命令,可以用来观察线上正在运行的方法的出入参: ```bash watch com.zhongyouex.org.provider.api.impl.UserInfoBusinessApiImpl queryWBLoginInfo {params[1],returnObj} -x 2 ``` 我们观察的还是这个用户查询服务 {params[1],returnObj} 这个参数的意思是打印方法的第二个参数和返回对象 -x 2 意思是打印的对象向下递归两层(如果不加这个参数,自定义对象或是List集合只会打印对象的内存地址信息,无法打印子属性,如果想显示全部属性,那么对象有几层嵌套,这个参数就要改为多少) **开启监听后我们再次调用这个方法,就输出了如下截图内容:** ![](//img1.jcloudcs.com/developer.jdcloud.com/4c855246-ea18-4317-b4fd-dc709542495320210706135355.png) 如果我们只想观察这个方法在异常时的情况可以这样输入: ``` watch com.zhongyouex.org.provider.api.impl.UserInfoBusinessApiImpl queryWBLoginInfo {params[1],throwExp} -e -x 2v ``` {params[1],throwExp} 的意思是输出第二个参数与返回的异常 -e的意思是观察的时间点是返回异常时(watch这个命令有4个观察点: -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后,如果不输入默认使用-f) #### 3.3 观察当前服务中是哪些线程在消耗CPU 当我们的服务在运行时我们还可以通过thread命令来快速定位消耗cpu的线程。 ``` thread -n 10 ``` 这个表示输出目前CPU消耗前10的线程 ![](//img1.jcloudcs.com/developer.jdcloud.com/29881c21-4e53-4aec-a4c9-77c69044634520210706135730.png) ### 4 实现原理 观察Arthas的功能我们发现他可以跟踪到JVM中正在运行的方法的变量,方法的堆栈。这个功能很像是idea的Debug功能。实际上这两个产品实现的思路也是一样的。都是通过JAVA虚拟机工具接口-JVMTI(JVM Tool Interface)来实现的。 JVMTI是JPDA(Java Platform Debugger Architecture)-Java 平台调试架构的一部分,是一套接口,我们需要用C或C++进行开发,实现其接口生成agent,在JVM的内部有很多事件的埋点,当这些埋点触发时,就是回调这些接口执行agent中的代码(例如idea的debug功能,是在启动时加的JAVA_OPTS=-agentlib:jdwp\=transport\=dt_socket,address\=127.0.0.1:50006,suspend\=y,server\=n来实现的)。 JAVA 1.5后为了使JAVA开发者能够生成agent,JDK提供了一个包java.lang.instrument。通过这个包可以让jvm访问JAVA版的agent,所以市上面的一些无代码侵入的黑科技一般都是用这个来做的(如jtrace,通过在启动时-javaagent:/export/servers/jtrace2-agent/pinpoint-bootstrap-2.0.1-SNAPSHOT.jar来进行植入的)。 JAVA1.6后 为了使开发者能够在启动JVM后动态的加载Agent包,增加了attach功能。可以在JVM进程外开发一个JAVA程序直接attach到运行的JVM上,动态传送JAR包进去如: ```java VirtualMachine virtualMachine = VirtualMachine.attach("端口号"); virtualMachine.loadAgent("jar包路径"); ``` 这种对现有功能提供扩展的大部分都是要对现有的类功能进行变更。这就会用到ASM\Javassist 这种字节码工具。 **那我们最后总结下流程就是:** - 启动Arthas后会通过选中的端口号连接到运行的JVM上 - 当我们输入watch命令后,会将监听类功能的代码用asm完成后打包成agent。 - 通过loadAgent功能将Jar包在JVM中运行。 - 运行Agent中的agentmain方法,将我们定义好的字节码变更代码放入回调钩子上(addTransformer(transformer))。 - JVM加载类后会触发回调第4步中的transformer中的代码,判断当前类是否需要增强,如果需要则运行。 ### 5 资料 Arthas:https://arthas.aliyun.com/doc/ jpda: https://www.ibm.com/docs/zh/sdk-java-technology/7?topic=tooling-jpda-tools instrument: https://docs.oracle.com/en/java/javase/11/docs/api/java.instrument/java/lang/instrument/package-summary.html ASM:https://asm.ow2.io/ ------------ ###### 自猿其说Tech-JDL京东物流技术发展部 ###### 作者:京喜达技术部 曲华丰
原创文章,需联系作者,授权转载
上一篇:GraphQL实战(3)-构建开发框架
下一篇:GraphQL实战(2)-java和spring boot实现
相关文章
安全测试之探索windows游戏扫雷
Jmeter压测实战:Jmeter二次开发之JSF采样器实现
Laputa自动化测试框架介绍
自猿其说Tech
文章数
426
阅读量
2149963
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
自猿其说Tech
文章数
426
阅读量
2149963
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号