关于这篇文章:Arthas 使用技巧与步骤-优快云博客
提到的【动态热修复】,专门总结了一下关于mc命令的使用。
详细使用说明,请参考官方文档:简介 | arthas
解释mc命令
mc(modify class)是Arthas中的“方法更改”命令,用于快速修改类方法体。其实mc代表的是“修改类”的功能,可以在命令行内提供Java代码片段,Arthas会将它编译并立即加载到目标类中。这使得可以在不重启应用程序的情况下,动态修改代码行为。
聪明的小伙伴,可以把它理解成一个内存编译器,用于将Java源代码即时编译为字节码,并通过retransform命令重新加载类。该命令的功能包括生成.class文件并支持热更新。
mc命令用途
mc命令能用于动态代码注入,它可以帮助创建一个“内存木马”。可通过参数 -c 来指定类加载器,-d 用于指定输出目录。命令语法为:
# mc -c:指定类加载器 -d:指定编译后字节码输出目录 JavaSourceFiles:修改的java文件列表
mc [-c <classloader>] [-d <output-dir>] <JavaSourceFiles>
下面是一些常用的命令指南
mc命令详细指南
1. mc 概述与原理
-
定位:
mc是 Arthas 在“类命令”一栏中提供的“Memory Compiler”命令,用于**将.java源文件在目标 JVM 内存中编译为.class。 -
原理:它基于 JDK 提供的
javax.tools.JavaCompilerAPI,遍历当前应用的类路径和依赖 JAR,将源码编译,并生成字节码,然后存放在内存中或指定目录。 -
热更新配合:通常编译完成后,结合
retransform(或redefine)命令,将新生成的字节码热加载到 JVM,完成线上代码替换而无需重启服务。
2. 基本用法
# 将 /tmp/Test.java 编译成字节码,输出到内存(默认位置)
mc /tmp/Test.java
-
这条命令会在内存中生成
Test.class,但不会写入磁盘。
# 指定输出目录,将编译后的 .class 写入磁盘
mc -d /tmp/output /tmp/ClassA.java /tmp/ClassB.java
-
-d参数后接目录路径,可将多个源码文件一起编译并输出。
# 指定 ClassLoader(通过 ID)
mc -c 327a647b /tmp/Test.java
# 或者通过 ClassLoader 类型全名
mc --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader /tmp/UserController.java -d /tmp
-
-c或--classLoaderClass可精确指定要使用的 ClassLoader,避免编译后的类载入到错误的 ClassLoader 中。
3. 与热更新命令配合(典型流程)
-
反编译原码
jad --source-only com.example.MyService > /tmp/MyService.java获取线上运行的源码。
-
修改源码
在/tmp/MyService.java中修正逻辑,比如打印、修复 bug。 -
内存编译
mc /tmp/MyService.java -d /tmp将修改后的源码编译为字节码,并输出到
/tmp/com/example/MyService.class。 -
热加载
retransform /tmp/com/example/MyService.class或者
redefine /tmp/com/example/MyService.class将新字节码注入 JVM,线上生效,无需重启。
4. 典型线上场景示例
场景:线上某业务方法逻辑有 bug,需要快速验证修复,而不重启服务。
# 1. 下载启动 Arthas
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
# 2. 反编译目标类
jad --source-only com.app.biz.OrderService > /tmp/OrderService.java
# 3. 编辑修复,保存 /tmp/OrderService.java
# 4. 内存编译并输出到 /tmp
mc /tmp/OrderService.java -d /tmp
# 5. 热更新到 JVM
retransform /tmp/com/app/biz/OrderService.class
# 6. 验证接口
curl http://127.0.0.1:8080/order/test
-
此流程在生产环境中可在几分钟内完成修复验证citeturn6view0。
5. 常见注意事项
-
JDK vs JRE
mc依赖javax.tools.JavaCompiler,必须在 JDK 环境下运行,JRE 会报 “Cannot load Java Compiler”。 -
编译失败或依赖缺失
-
如果源码引用第三方类,
mc会根据当前 ClassLoader 搜索依赖;若找不到,编译失败。 -
可先在本地用
javac完整编译,或用-classpath参数手动指定 classpath(高级用法)。
-
-
ClassLoader 匹配
-
默认情况下
mc使用当前 Shell 会话所附加的 ClassLoader,若要修改 Web 应用下的 Spring Boot 加载器,需用-c/--classLoaderClass明确指定。
-
-
不支持新增字段或方法
redefine/retransform均不允许新增类的字段或方法,仅支持修改现有方法体。 -
安全与风险
-
线上热更新风险较大,只应在紧急场景下使用,并在验证通过后进行正式发布。
-
完成诊断后,执行
reset命令恢复所有增强,或stop退出 Arthas,以清理临时字节码。
-
6. 最佳实践
-
预先校验:将源码在本地或测试环境先用
mc+retransform验证再线上操作。 -
脚本化流程:将上述命令封装入脚本,减少手动输入风险。
-
日志与审计:记录所有
mc、retransform操作及输出目录,便于事后审计和回滚。 -
限流监控:在高并发场景下,先限流再热更新,防止线上抖动。
通过上述讲解,你可以从原理到实战全方位掌握 Arthas mc 命令的使用,做到“无需重启、快速定位、即时修复”。
4258

被折叠的 条评论
为什么被折叠?



