文章目录
- 1. 背景介绍
- 2. 安装下载
- 3. 常用命令
- 4. 常见案例
- 4.1 案例一:使用logger 实时修改某个类的日志级别、
- 4.2 案例二:使用watch 查看方法输入输出参数
- 4.3 案例三:使用 Arthas 实现在线代码热更新
1. 背景介绍
通常,本地开发环境无法访问生产环境。如果在生产环境中遇到问题,则无法使用 IDE 远程调试。更糟糕的是,在生产环境中调试是不可接受的,因为它会暂停所有线程,导致服务暂停。如果您正在考虑在代码中添加一些日志以帮助解决问题,您将必须经历以下阶段:测试、预发,然后生产。这种方法效率低下,更糟糕的是,该问题可能无法解决,因为一旦 JVM 重新启动,它可能无法复现,如上文所述。
Arthas(阿尔萨斯)能为你做什么?
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到 JVM 的实时运行状态?
怎么快速定位应用的热点,生成火焰图?
怎样直接从 JVM 内查找某个类的实例?
2. 安装下载
官方文档:https://arthas.aliyun.com/doc/
本文在docker容器背景下操作
查看是否安装curlwhich curlcurl --version
下载curl -O https://arthas.aliyun.com/arthas-boot.jarwget https://arthas.aliyun.com/arthas-boot.jar
启动java -jar arthas-boot.jar
3. 常用命令
详见:https://arthas.aliyun.com/doc/commands.html
jvm 相关dashboard - 当前系统的实时数据面板getstatic - 查看类的静态属性heapdump - dump java heap, 类似 jmap 命令的 heap dump 功能jvm - 查看当前 JVM 的信息logger - 查看和修改 loggermemory - 查看 JVM 的内存信息ognl - 执行 ognl 表达式perfcounter - 查看当前 JVM 的 Perf Counter 信息sysenv - 查看 JVM 的环境变量sysprop - 查看和修改 JVM 的系统属性thread - 查看当前 JVM 的线程堆栈信息vmoption - 查看和修改 JVM 里诊断相关的 optionvmtool - 从 jvm 里查询对象,执行 forceGc
class/classloader 相关classloader - 查看 classloader 的继承树,urls,类加载信息,使用 classloader 去 getResourcedump - dump 已加载类的 byte code 到特定目录jad - 反编译指定已加载类的源码mc - 内存编译器,内存编译.java文件为.class文件redefine - 加载外部的.class文件,redefine 到 JVM 里retransform - 加载外部的.class文件,retransform 到 JVM 里sc - 查看 JVM 已加载的类信息sm - 查看已加载类的方法信息
monitor/watch/trace 相关monitor - 方法执行监控stack - 输出当前方法被调用的调用路径trace - 方法内部调用路径,并输出方法路径上的每个节点上耗时tt - 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测watch - 方法执行数据观测
基础命令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 命令类似version - 输出当前目标 Java 进程所加载的 Arthas 版本号
PS: 靠,好像没有ls、ll、touch类似的linux命令,不方便!
重点:logger、sc、watch 、mc、refine
4. 常见案例
4.1 案例一:使用logger 实时修改某个类的日志级别、
# 1. logger查看指定类的日志级别
logger --name com.nimbus.messagecenter.service.impl.MessageSendServiceImpl
不支持:*.MessageSendServiceImpl# 2. sc 命令查看 JVM 加载的类信息【目的是获取classLoaderHash】
sc -d com.nimbus.messagecenter.service.impl.MessageSendServiceImpl
支持:sc -d *MessageSendServiceImpl# 3. logger 命令修改指定类的日志级别
logger -c 7daf6ecc --name com.nimbus.messagecenter.service.impl.MessageSendServiceImpl --level debug
4.2 案例二:使用watch 查看方法输入输出参数
target : the object
clazz : the object's class
method : the constructor or method
params : the parameters array of method
params[0..n] : the element of parameters array
returnObj : the returned object of method
throwExp : the throw exception of method
isReturn : the method ended by return
isThrow : the method ended by throwing exception
#cost : the execution time in ms of method invocation
查看入参: watch com.nimbus.messagecenter.service.impl.MessageSendServiceImpl sendMessage params
查看返回值:watch *MessageSendServiceImpl sendMessage returnObj
查看异常: watch *MessageSendServiceImpl sendMessage throwExp
4.3 案例三:使用 Arthas 实现在线代码热更新
# 1. 使用 sc 命令查找 JVM 加载的类信息
sc -d *MessageSendServiceImpl
# 2. 使用 jad 命令反编译已加载类的源码
jad --source-only com.nimbus.messagecenter.service.impl.MessageSendServiceImpl > MessageSendServiceImpl.java
# 3. 修改改文件代码【但是docker容器中没有vim编辑器,草】
# 4. 使用 mc 内存编译.java文件为.class文件
mc -c 7daf6ecc MessageSendServiceImpl.java -d /tmp
# 5. 使用 redefine 加载外部的.class文件
redefine /tmp/MessageSendServiceImpl.class