暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

性能调优必备:Arthas安装及常用命令教程

程序员杨叔 2022-02-13
493

一. 背景介绍



Arthas 是 Alibaba 在 2018 年 9 月开源的 Java 诊断工具。支持 JDK6+, 采用命令行交互模式,提供 Tab 自动补全,可以方便地定位和诊断线上程序运行问题。得益于 Arthas 强大且丰富的功能,让 Arthas 能做很多的事情,比如以下场景:

  • 是否有一个全局视角来查看系统的运行状况?

  • 为什么 CPU 又升高了,到底是哪里占用了 CPU ?

  • 运行的多线程有死锁吗?有阻塞吗?

  • 程序运行耗时很长,是哪里耗时比较长呢?如何监测呢?

  • 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?

  • 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?




二. 安装和启动



在服务器上输入以下安装命令:
wget https://arthas.aliyun.com/arthas-boot.jar

系统会下载arthas-boot.jar, 要启动arthas就直接运行这个jar包:
java -jar arthas-boot.jar
arthas-boot是Arthas的启动程序,它启动后,会列出所有的Java进程,用户可以选择需要诊断的目标进程。

attach成功后,会看到Arthas的logo,启动成功:

快速退出某个命令:Q或者Ctrl+C
退出Arthas: exit或者quit, 退出当前session,Arthas server还在目标进程中运行。
彻底退出stop. 用完一定要stop哦,避免Arthas server依然运行占用系统资源。



三. 使用trace命令定位代码耗时



性能测试过程中,经常会碰到接口请求耗时长,但是又不知道具体是哪个环节哪段代码耗时长。这个时候Arthas的trace命令的作用就体现出来了,可以方便快捷从方法表层顺着调用链路一步步往下追踪,最终找出具体耗时长的代码块,是性能测试优化的神器。

举例:假设用例列表页有性能问题,加载列表耗时长,下面介绍如何使用Arthas一步一步定位到具体是哪段代码耗时长:

通过浏览器F12查看network,找到请求URL为: /getList,反查代码,可以知道Controller层面的方法名:getList:

回到服务器上,使用trace命令:
trace com.xxxx.controller.DubboCaseController getList ‘#cost > 2’

  • com.xxxx.controller.DubboCaseController是controller的路径和类名

  • getList是方法名

  • '#cost > 2' 表示查找耗时大于2ms的方法


trace结果如下图:


根据提示,是DubboCaseService下的getList()方法标红耗时长。那就继续往下查:
trace com.xxxx.service.DubboCaseService getList ‘#cost > 2’

得到getListWithoutCount方法耗时长

继续往下:
trace com.xxxx.service.impl.DubboCaseServiceImpl getListWithoutCount ‘#cost > 2’

得到getAllByMavenId方法耗时长


到此已经定位到是这段SQL耗时比较长,可以针对性的优化SQL当然上述举例是代码逻辑比较简单,所以最终反映是在SQL上耗时长。如果代码逻辑复杂,那可能定位到的就是前面某个代码方法的逻辑耗时长了,那就可以针对那个代码方法做优化。



四、其他常用命令使用介绍






1. thread命令:查看线程


用thread命令列出线程的信息:

如果发现某个线程CPU使用过高,通过thread加线程id输出该线程的栈信息:

从输出结果可以看到这个线程处于运行状态,在执行的具体某个方法,方法中的代码行号。这样就可以去找到对应的代码块,定位问题。

thread -n 3 查看CPU使用率top n线程的栈:


thread -b 找出当前阻塞其他线程的线程。有时候我们发现应用卡住了, 通常是由于某个线程拿住了某个锁, 并且其他线程都在等待这把锁造成的。为了排查这类问题, arthas提供了thread -b, 一键找出那个罪魁祸首:




2. Dashboard命令:查看系统的实时面板


命令:dashboard, 每5秒刷新一次面板

比如内存泄漏:如果内存使用率在不断上升,而且gc后也不下降,后面还发现gc越来越频繁,很可能就是内存泄漏了。这个时候我们可以直接用heapdump命令:heapdump --live /root/jvm.hprof 把内存快照dump出来,作用和jmap工具一样(jmap -dump:live):

下载下来,再使用内存dump分析工具,比如:MAT( Eclipse Memory Analyzer),分析可能泄露的内存原因:




3. watch命令:查看指定方法的调用情况


watch com.xxxx.xxxxController update “{params,returnObj}” -x 3 -b -s,查看xxxxController的update方法的返回值:

-x 3是指定输出结果的属性遍历深度,默认为 1
-b方法调用前观察,用于返回方法入参
-s方法调用后观察,用于返回方法返回值


备注:更多的时候,是用于这个方法代码里面你没输出日志,临时看一下入参&返回结果定位问题。而不用重新去加日志打印的代码,重新发布应用。




4. monitor命令:监控方法的执行情况


包括:成功次数、失败次数、平均响应时间、失败率
monitor -c 10 com.xxxx.xxxxController update
- 监控update这个方法的执行情况
- -c 10 指定统计周期为10秒统计一次,默认是120秒统计一次




5. tt命令


TimeTunnel:记录下方法执行数据的时空隧道
tt -t com.xxxx.xxxxController list


INDEX: 时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要。
TIMESTAMP: 方法执行的本机时间,记录了这个时间片段所发生的本机时间
COST(ms): 方法执行的耗时
IS-RET: 方法是否以正常返回的形式结束
IS-EXP: 方法是否以抛异常的形式结束
OBJECT: 执行对象的hashCode(),注意,曾经有人误认为是对象在JVM中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体
CLASS: 执行的类名
METHOD: 执行的方法名

通常该命令是用于:根据之前的记录直接重做一次调用。
因为有的时候调用不是那么好触发的,这个时候这个命令就比较有用,可以快速重新调用一次:
tt -i 1003 -p   表示重做Index为1003的那次调用




6. stack命令:监控方法的被执行的路径


很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从哪里被执行了,此时你需要的是 stack 命令, 主要用于监控方法被谁调用了:
stack com.xxxx.xxxxController list




7. sm命令


用途:搜索出所有已经加载了 Class 信息的方法信息
sm -d com.xxxx.xxxxController




8. jad命令:反编译指定已加载类的源码


jad com.xxxx.xxxxController

反编译源码到指定文件:
jad --source-only com.xxxx.xxxxController > /tmp/xxxxController.java
-source-only表示只打印源码,如果不加这个参数,
在反编译出的内容头部会携带类加载器的信息,内容太多

-/tmp/xxxxController.java 表示打印到tmp文件夹下xxxxController.java文件中




9. logger命令:实现动态更新logger level


使用sc命令查看你需要改变的类信息,关注classLoaderHash
sc -d com.xxxx.xxxxController


logger -c 70ac4376 查看当前的日志级别

查看具体某一个name的日志级别:logger -c 70ac4376 --name com.xxxx.xxxx

将日志级别改为info: 
logger -c 70ac4376 --name com.xxxx.xxxx --level info




10. 其他说明


Arthas还可以通过使用一系列命令:jad>mc>redefine热更新线上代码,实现不重新发版试验新代码效果。但研发一般不敢在生产环境轻易用这个功能,因为:

  • 黑屏化的操作可能会导致误操作

  • 不符合安全生产的规范,不满足可监控、可回滚、可降级

Arthas中文版指导文档:
https://arthas.aliyun.com/doc/arthas-tutorials.html?language=cn&id=arthas-basics



END



以上,如果对你有帮助,

欢迎关注程序员杨叔的微信公众号,免费获取更多测试开发干货内容资料:

文章转载自程序员杨叔,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论