Arthas实践

4,426 阅读6分钟

1.是什么?解决什么样的问题?

Arthas(阿尔萨斯)是阿里巴巴开源的 Java 诊断工具,深受开发者喜爱。

当你遇到以下类似问题而束手无策时,Arthas 可以帮助你解决:

  • 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  • 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  • 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  • 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  • 是否有一个全局视角来查看系统的运行状况?
  • 有什么办法可以监控到JVM的实时运行状态?
  • 怎么快速定位应用的热点,生成火焰图?

Arthas 采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

实际摸索起来,你会发现Arthas的功能是 非常强大 的,再也不用加班查问题了。

2.为什么需要它?

很多公司对于应用有相对完善的apm监控体系,能够涵盖和解决大部分场景下的问题;

Arthas的出现,并不是要去替代apm,而且命令式的交互其实还没有图形化的监控系统来的更加直观;

Arthas可以跟已有的监控体系结合,在适当的场景去运用它,帮助我们更快更好的去解决问题,提升效率才是关键;

(似乎es apm更香?)

3.快速启动

wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar

通过wget命令直接获取arthas-boot应用包;

Arthas是一个java应用,通过java -jar启动,arthas会通过jps命令扫描当前系统的java进程,并打印对应应用ID;

选择要诊断的java应用序号,回车即可attach上去进入Arthas控制台; 然后,冲吧!

4.常用命令列举

命令功能
dashboard当前系统的实时数据面板
sc查看JVM已加载的类信息
sm查看已加载类的方法信息
jad反编译指定已加载类的源码
thread查看当前JVM的线程堆栈信息
watch方法执行数据观测
trace方法内部调用路径,并输出方法路径上的每个节点上耗时
stack输出当前方法被调用的调用路径
tt方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
monitor方法执行监控
classloader查看 classloader的继承树,urls,类加载信息
heapdump类似jmap命令的 heap dump功能

4.1.dashboard

定义:

  • 当前系统的实时数据面板;
  • 查看线程,虚拟机,运行时状态信息;

命令: dashboard -i 5000 -n 1

使用场景: 应用总体问题排查,异常线程查看等;

4.2.sc

定义:

  • 查看JVM已加载的类信息;

  • 查看类信息,来源,继承关系,类加载器;

命令: sc -d ClassName

使用场景:

类加载异常相关问题如 ClassNotFoundException, ClassCastException, ClassNoDefException…

(开发过程中经常需要依赖第三方包,而不同的包版本混淆可能导致相关类异常,可以直接通过此命令直接定位目标类的来源)

4.3.sm

定义:

  • 查看已加载类的方法信息;

  • 指定类下所有方法名,出入参类型;

命令: sm -d ClassName method

使用场景:: 方法相关异常 NoSuchMethodException

(感觉不是很实用,泛型也不支持)

4.4.jad

含义: 反编译指定已加载类的源码;

命令: jad —source-only ClassName

使用场景:

  • 指定代码改动是否提交;

  • 查看代码源码;

(可直接排查改动代码后打包上线却没有生效的玄学问题)

4.5.thread

含义:

thread -n: 查询占用cpu最高的前n个线程

thread id:查看指定线程堆栈

thread -b:查看当前阻塞其他线程的线程

使用场景: 排查应用请求响应慢,锁等待,异常线程定位

(让我看看是哪位同学在代码里下毒)

4.6.watch

含义: 方法执行数据观测;

命令: watch ClassName method ‘{params[0],returnObj}’ -x n

使用场景: 确定线上调用出入参,观察方法调用;

(让我来看看你给我丢的什么鬼参数???)

4.7.trace

含义: 方法内部调用路径,并输出方法路径上的每个节点上耗时;

命令: trace ClassName method

使用场景:

  • 确定接口耗时节点;

  • 查看方法执行实际调用路径;

(耗时节点一抓就着,稳!)

4.8.stack

含义: 输出当前方法被调用的调用路径;很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令;

命令: stack ClassName method -n 5 '1==1'

使用场景:

查看方法执行实际调用路径,源代码中看不懂代码执行路径的,直接上这个;

4.9.tt

含义: 记录下指定方法每次调用的入参和返回信息并能对这些不同的时间下调用进行观测;

命令:

tt -t ClassName method

tt -i index

使用场景:

  • 查看方法调用记录;

  • 查看异常方法,堆栈;

4.10.profiler 火焰图

含义: 支持生成应用热点的火焰图。本质上是通过不断的采样,然后把收集到的采样结果生成火焰图;

命令: start --event cpu --interval 10000000

使用场景:

通过火焰图排查应用性能问题;

4.11.ognl+Arthas(获取任意spring bean)

使用tt命令获取到spring context

tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod

tt -i 1000 -w ‘target.getApplicationContext().getBean("activityAdapterServiceImpl").findByUid("111")

ognl '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, #context.getBean(“activityServiceImpl").findByUid("111")'

5. ognl表达式支持

Arthas集成了ognl表达式支持,方便我们结合进行在线调试,编写观察表达式等等。

定义: Object-Graph Navigation Language(对象图导航语言);

支持类静态的方法调用和值访问:

@[类全名]@[方法名|值名]

exp:

ognl ‘@java.lang.System@out.println("hello)’

ognl ‘@com.seewo.SeewoResource@APP_CODE’

ognl -c 7f9a81e8 ‘@org.springframework.boot.SpringApplication@logger’

总结:ognl有一个上下文(OgnlContext)概念,底层一个Map结构

OGNL语言介绍及实践:developer.ibm.com/zh/articles…

6.Arthas idea plugin

命令记不住?idea插件走起!

目标: 简化命令构造,使用便捷;

使用场景: 处理线上问题最快速输出便捷的调试命令;

使用时在指定需要调试的地方右键,选择命令,一键copy,去Arthas控制台粘贴回车执行即可,真香

安装地址:plugins.jetbrains.com/plugin/1358…

使用说明:www.yuque.com/docs/share/…

7.命令总结

8.最后

  • 1.对于开发过程中的问题排查,需要做到有理有据;

  • 2.根据我们的经验和知识体系去假设推敲,通过工具辅助我们验证和解决问题;

  • 3.多思考,学习和实践去提高研发效率;