1.Arthas简介快速入门
- 阿里开源的Java诊断工具,它可以在运行时对Java应用程序进行动态诊断和调试
- 当你遇到以下类似问题而束手无策时,
Arthas
可以帮助你解决
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到 JVM 的实时运行状态?
怎么快速定位应用的热点,生成火焰图?
怎样直接从 JVM 内查找某个类的实例?
github地址:https://github.com/alibaba/arthas
版本:Arthas-3.6.7
环境说明
Arthas 支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,
提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断
也支持浏览器直接访问对应的ip+端口,固定端口 8563
默认情况下,arthas 只 listen 127.0.0.1,所以如果想从远程连接,使用 --target-ip参数指定 listen 的 IP
快速使用
启动 java -jar arthas-boot.jar
运行日志路径 ~/logs/arthas/arthas.log
退出 arthas
如果只是退出当前的连接,其他客户端不受影响,可以用 quit或者exit命令
目标进程上的 arthas 还会继续运行,端口保持开放,下次连接时执行java -jar arthas-boot.jar可以直接连接上
如果想完全退出 arthas,可以执行stop命令
2.Arthas常用基础命令实战
- version - 输出当前目标 Java 进程所加载的 Arthas 版本号
- base64 - base64 编码转换,和 linux 里的 base64 命令类似
cat - 打印文件内容,和 linux 里的 cat 命令类似
cls - 清空当前屏幕区域
echo - 打印参数,和 linux 里的 echo 命令类似
grep - 匹配查找,和 linux 里的 grep 命令类似
help - 查看命令帮助信息
history - 打印命令历史
keymap - Arthas 快捷键列表及自定义快捷键
pwd - 返回当前的工作目录,和 linux 命令类似
quit - 退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
reset - 重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
session - 查看当前会话的信息
stop - 关闭 Arthas 服务端,所有 Arthas 客户端全部退出
tee - 复制标准输入到标准输出和指定的文件,和 linux 里的 tee 命令类似
3.Arthas常用JVM命令案例实战
(1)JVM相关的命令
- dashboard - 当前系统的实时数据面板
heapdump - dump java heap, 类似 jmap 命令的 heap dump 功能
jvm - 查看当前 JVM 的信息
memory - 查看 JVM 的内存信息
ognl - 执行 ognl 表达式
perfcounter - 查看当前 JVM 的 Perf Counter 信息
sysenv - 查看 JVM 的环境变量
sysprop - 查看和修改 JVM 的系统属性
thread - 查看当前 JVM 的线程堆栈信息
vmoption - 查看和修改 JVM 里诊断相关的 option
(2)dashboard - 当前系统的实时数据面板
- 整体大面板
- 顶部-线程的基本信息
字段 | 说明 |
id | Java 级别的线程 ID |
name | 线程名称 |
group | 线程组名称 |
proirity | 线程优先级,1 ~ 10 之间的数字,越大优先级越高 |
state | 线程的状态 |
cpu | 线程的 cpu 使用率 |
lta_time | 上次采样之后线程运行增量 CPU 时间,数据格式为秒 |
time | 线程运行总 CPU 时间,数据格式为 分:秒 |
interupted | 当前线程是否中断 |
daemon | 是否是 daemon 守护线程 |
- 中部-堆内存的使用情况
字段 | 说明 |
used | 当前使用了多少内存 |
total | 总共分配了多少内存 |
max | 最大使用了多少 |
usage | 使用比例 |
gc | 垃圾回收器 |
- 底部-操作系统信息,JDK版本
(3)thead - 查看当前 JVM 的线程堆栈信息
- 常用参数
- –all :显示所有匹配的线程,默认就是第一页线程信息
- -i:设置cpu统计时的采样间隔,单位为毫秒
thread -i 2000
- [ id ]:查看指定ID的线程堆栈
thread 54
- -n :查看CPU使用率最高的TopN个线程, 如果值为-1表示显示所有线程
thread -n 3
-b :展示阻塞线程 thread -b
–state : 根据线程状态筛选线程 thread --state TIMED_WAITING
状态类型:NEW, RUNNABLE, TIMED_WAITING, WAITING, BLOCKED,TERMINATED
(4)heapdump - 类似 jmap 命令的 heap dump 功能
- 生成堆栈快照
heapdump /Users/mac/Desktop/heapdump.hprof
(5)jvm - 查看当前 JVM 的信息
(6)sysenv - 查看 JVM 的环境变量
(7)sysprop - 查看和修改 JVM 的系统属性
- 查看所有属性:sysprop
- 查看单个属性:sysprop java.version
- 修改某个属性:sysprop user.country CN
(8)sc - 查看 JVM 已加载的类信息
- -d 详情,-f 类属性输出
sc -d -f com.lixiang.controller.SpringTestController
(9)sm - 查看已加载类的方法信息
sm -d com.lixiang.controller.SpringTestController
(10)jad - 反编译指定已加载类的源码
- 反编译整个类
jad com.lixiang.SpringTestApplication
- 通过
--source-only
选项,可以只打印源代码
- 应用场景
- 查看某个类的业务逻辑,方法逻辑
- 查看本地修改的代码是否线上成功生效
4.Arthas方法诊断命令案例实战
(1)monitor - 方法执行监控
- 非实时响应,需要对应的方法有被调用才行,所以需要触发web接口请求
- 监视一个时间段中指定方法的执行次数,成功次数,失败次数,耗时等这些信息
monitor -c 2 com.lixiang.controller.SpringTestController query
(2)stack - 输出当前方法被调用的调用路径, 一个方法被执行的路径非常多,不知道这个方法是从那里被执行,就可以采用
- 案例
stack com.lixiang.controller.SpringTestController query
(3)trace - 方法内部调用,输出方法路径上的每个节点上耗时, 定位因 RT 高导致的性能问题
- 每次只能跟踪一级方法的调用链路
- 案例输出全部方法
trace com.lixiang.controller.SpringTestController *
ts: 时间戳,表示日志记录的时间,该字段的值为2023年3月26日下午5点48分46秒。
thread_name: 线程名称,表示当前执行该日志记录的线程名称,该字段的值为http-nio-8080-exec-10。
id: 线程ID,表示当前执行该日志记录的线程ID,该字段的值为20。
is_daemon
: 是否为守护线程,该字段的值为true,表示该线程是守护线程。priority
: 线程优先级,该字段的值为5,表示该线程的优先级为5。TCCL
: 线程上下文类加载器,表示当前线程的上下文类加载器为TomcatEmbeddedWebappClassLoader。
默认情况下,trace不会包含jdk里的函数调用,如果希望trace jdk里的函数, 需要显式设置–skipJDKMethod false
即 trace --skipJDKMethod false com.lixiang.controller.SpringTestController *
(4)watch - 方法执行数据观测
- 应用场景:查看方法调用栈,参数入参,返回值等调试
- 默认的 观察表达式,默认值是
{params, target, returnObj}
- 也可以指定观察返回值
watch com.lixiang.controller.SpringTestController * {params,returnObj}
- 展开里面具体的值 -x 参数表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是 1, 最大是4。
watch com.lixiang.controller.SpringTestController * {params,returnObj} -x 4
5.Arthas在线调试案例实战
- 生产环境运行了java程序,需要在线调试,在不重启JVM程序,动态调整,打印参数或修改方法内部逻辑。
- 步骤以及环境准备
- 第一步:jad 把字节码文件反编译成源代码
- 第二步:mc 在内存中把源代码编译成字节码文件
- 第三步:redefine 把新生成的字节码文件在内存中执行