1.Arthas简介快速入门
-
阿里开源的Java诊断工具,它可以在运行时对Java应用程序进行动态诊断和调试
-
当你遇到以下类似问题而束手无策时,
Arthas
可以帮助你解决- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到 JVM 的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
- 怎样直接从 JVM 内查找某个类的实例?
-
github地址:https://github.com/alibaba/arthas
-
官网:https://arthas.aliyun.com/
-
版本: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 使用率 |
delta_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 把新生成的字节码文件在内存中执行