简介
Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到 JVM 的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
- 怎样直接从 JVM 内查找某个类的实例?
下载
下载jar包
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
下载全量包,其中也包含arthas-boot.jar
https://arthas.aliyun.com/download/latest_version?mirror=aliyun
使用
java -jar arthas-boot.jar
选择要attach进程,之后进入Arthas的交互式界面。
命令示例
memory #查看内存信息
ognl '@className@field' #查询静态类的静态字段值
jad class_name #反编译指定类,内部是使用cfr库来实现的
更多命令可以查询官方文档
遇到的问题
运行Arthas的jdk版本必须和要attach的java进程的jdk版本一致,不然就会抛异常
[ERROR] Start arthas failed, exception stack trace:
com.sun.tools.attach.AttachNotSupportedException: Unable to attach to 64-bit process
at sun.tools.attach.WindowsVirtualMachine.openProcess(Native Method)
at sun.tools.attach.WindowsVirtualMachine.<init>(WindowsVirtualMachine.java:56)
at sun.tools.attach.WindowsAttachProvider.attachVirtualMachine(WindowsAttachProvider.java:69)
at com.sun.tools.attach.spi.AttachProvider.attachVirtualMachine(AttachProvider.java:194)
at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:250)
at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:102)
at com.taobao.arthas.core.Arthas.<init>(Arthas.java:27)
at com.taobao.arthas.core.Arthas.main(Arthas.java:161)
当时两个版本分别为jdk8和jdk11。
简单原理分析
java -jar arthas-boot.jar
- 启动类为 com.taobao.arthas.boot.Bootstrap
- 先使用jdk提供的jps命令查询出所有进程,去除当前程序的
- 再运行com.taobao.arthas.client.TelnetConsole的main()方法
- 再运行arthas-core.jar,实际上是com.taobao.arthas.core.Arthas类的main()方法
- 在Arthas类中,使用VirtualMachine将
arthas-agent.jar
attach到我们的目标程序上 - 执行AgentBootstrap类的agentmain(String,Instrumentation)方法
- 使用Instrumentation对象来创建com.taobao.arthas.core.server.ArthasBootstrap类
- ArthasBootstrap内部会创建Netty服务器来监听客户端命令并处理
参考
Arthas官网
Arthas源码-github
java反编译器cfr
Java Agent入门
Arthas原理:如何做到与应用代码隔离?