文章目录
- 概述
- arthas是什么呢?
- arthas能解决哪些问题呢?
- 安装和启动arthas
- 从一个全局视角来查看系统的运行状况
- 线上出现问题,线下无法重现,利用arthas进行调试——“线上调试”
- 1 使用watch。
- 2 使用tt。
- 3 使用stack。
- 服务RT latency 上升,如何定位慢调用?
- 1 使用trace 。
- 2 使用monitor。
- 服务运行状态和预期不一致,可通过arthas排查是否是代码是正确的或者类加载是正确的。
- 1 使用sc
- 2 使用sm
- 3 使用jad
- 找到当前阻塞其他线程的线程
- 1 使用thread
- 注意事项
- arthas使用完成后务必使用shutdown命令关闭已经加载的arthas相关服务。
- 为什么?
- 改动jdk原生类务必小心(java.*)。
- 为什么?
- 如果启用远程连接,启动arthas时输入的ip和端口都是本机暴露给外界的ip和端口
- 为什么?
概述
接触arthas还是从greys开始的,刚开始听同事推荐greys,觉得很强大,后来查阅资料,也听了组内其他人的推荐,了解到arthas这个东西,它是greys的升级版,性能和功能上都要更胜一筹,所以我花了一些时间去系统学习了下arthas的源码。本片基于arthas官方文档,并加上自己的理解,尽量对arthas进行一个较为系统的介绍,由于能力有限,如果有不对之处欢迎指正。着重介绍一下,接下来这里将是几篇文章形成的系列内容,包含arthas的使用、原理以及源码,各位有兴趣可以持续关注下。
arthas是什么呢?
arthas是阿里巴巴中间件团队开源出来的Java诊断工具。功能强大, 执行性能也是非常好。于2018年9月正式开源, 目前github的star数已经超过1W+.
Github地址:https://github.com/alibaba/arthas
arthas能解决哪些问题呢?
1 从一个全局视角来查看系统的运行状况
2 线上出现问题,线下无法重现,利用arthas进行调试
3 服务RT latency 上升,如何定位慢调用
4 服务运行状态和预期不一致,可通过arthas排查是否是代码是正确的或者类加载是正确的
5 找到当前阻塞其他线程的线程
安装和启动arthas
使用 wget https://alibaba.github.io/arthas/arthas-boot.jar 下载arthas-boot.jar,使用java -jar arthas-boot.jar启动arthas。选择要监控的目标进程,而后就可以进行对arthas的操作了。
从一个全局视角来查看系统的运行状况
使用Dashboard:,能够查新系统整体的运行面板:
线上出现问题,线下无法重现,利用arthas进行调试——“线上调试”
1 使用watch。
该命令可以方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写OGNL 表达式进行对应变量的查看.(详细使用参考文档https://alibaba.github.io/arthas/watch.html )
这里值得一提的是,打印出的各个参数可能不是很直观,这里可用命令 options json-format true 来使参数以json的形式打印出来。
2 使用tt。
watch 虽然很方便,也很灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。
这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。
3 使用stack。
当出现线上问题时,往往一个方法的调用路径非常多,我们需要知道出问题的方法的调用路径是具体是什么,这时就需要用到stack命令。
服务RT latency 上升,如何定位慢调用?
1 使用trace 。
trace命令可以输出方法内部调用路径,并输出方法路径上的每个节点上耗时。trace 能方便的帮助你定位和发现因 RT 高而导致的性能问题缺陷,但其每次只能跟踪一级方法的调用链路,这是因为trace是代价比较贵的,多层trace可能会导致最终要trace的类和函数非常多,导致性能会受到很大的影响。
2 使用monitor。
monitor 命令是一个非实时返回命令.这也是和trace命令最大的区别。trace的实时返回就注定了trace命令不能承担方法调用和返回情况的一些统计任务。monitor承担的任务就是对该类数据的统计工作,包含方法在固定时间段内的调用次数、成功次数、失败次数、平均响应时间、失败率等数据。trace和monitor的有效结合,能对性能瓶颈的定位更加准确高效。
注意:trace 在执行的过程中本身是会有一定的性能开销,在统计的报告中并未像 JProfiler 一样预先减去其自身的统计开销。所以这统计出来有些许的不准,渲染路径上调用的类、方法越多,性能偏差越大。但还是能让你看清一些事情的。
服务运行状态和预期不一致,可通过arthas排查是否是代码是正确的或者类加载是正确的。
1 使用sc
“Search-Class” 的简写,使用sc命令搜索出JVM已经加载的类的概要信息、详细信息、类的Field信息,从而帮助排查加载的类是否是自己预期要加载的类,从而帮助我们解决问题。如果不是预期要加载的类,则立马反应到应该是jar包冲突,如果类加载是正确的,但是方法执行却没有按照预期,则可怀疑是否是代码不是最新的。
2 使用sm
“Search-Method” 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。个人感觉该方法比较鸡肋。因为该方法也是只能展示方法的概要信息,如果是因为jar包冲突导致的方法调用错误,则sm打印出的内容也不足以看出异常。如果是因为代码没有更新到最新,则更不能看到什么异常了。如果方法定义的异常,则编译期应该就过不了。
3 使用jad
使用 jad反编译指定已加载类的源码是否是自己最新提交的代码,可以非常清晰的看到方法的源码是什么,原理就是jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,因为需要虚拟机的byte code 反编译,所以可能会比较消耗jvm的性能,该方法使用时还是要谨慎。
找到当前阻塞其他线程的线程
1 使用thread
Thread 查看当前线程信息,查看线程的堆栈, thread -b, 找出当前阻塞其他线程的线程 ,不过目前只支持找出synchronized关键字阻塞住的线程。
注意事项
arthas使用完成后务必使用shutdown命令关闭已经加载的arthas相关服务。
为什么?
shutdown会做两件事,1 关闭监听事件的ShellService。2 恢复被增强的类。如果没有shutdown的话,第一ShellService会浪费主机资源,第二增强的类一直工作,会给服务带来无必要的性能开销。
改动jdk原生类务必小心(java.*)。
为什么?
对系统级别的类进行增强,可能导致把JVM搞挂,一定要慎重选择!
如果启用远程连接,启动arthas时输入的ip和端口都是本机暴露给外界的ip和端口
为什么?
可能是arthas为了安全考虑的一个限制,如果使用默认的ip的话,远程主机将连不上,如果制定了本级暴露给外界的ip,才能进行远程连接,远程连接命令为:telnet ip port
或者http://ip:port