【基础篇】八、Arthas实现热部署

发布时间:2023年12月29日

1、Arthas实现热部署

实现热部署指的是在服务不停止的情况下,动态地更新字节码文件到内存中,即:把修复后的类的字节码文件更新到内存中,让类加载器重新加载

背景:修复了一个小bug,比如更改了一行代码,嫌弃重新打包部署太慢,想尽快看到效果

实现方式:

  • 服务器上(或服务pod里)java -jar arthas.jar启动Arthas
  • 执行:jad --source-only 要修改的类的全类名 > 目录/文件名.java 来反编译出源码到java文件
  • vi修改源码
  • 执行:mc –c 类加载器的hashcode 目录/文件名.java -d 输出目录,mc来编译新修改过的这个java文件
  • 执行:retransform class文件所在目录/xxx.class,重新加载新的字节码

2、示例

项目中的服务采用k8s部署,这里以服务A为例,首先将arthas的jar从hostPath拷贝到pod内:

kubectl cp /root/arthas-boot.jar  podName:/   -n namespace

启动:

java -jar arthas-boot.jar 
//选择PID

在这里插入图片描述

反编译要修改的类的源码:

在这里插入图片描述

修改java文件的源码,这里容器对应镜像的基础镜像是OpenJDK,没有vi,我先退出阿尔萨斯,cp到hostPath再编辑

kubectl cp podName:xx.java -n namespace /root/xx.java
//kubectl cp报错removing leading /

和从hostPath拷贝到pod不同,从pod到hostPath,有两个注意点:

  • hostPath不能是目录,是一个文件,也即不能是/root,而是/root/xx.java
  • podName后面的路径不能是绝对路径,而是从容器workdir开始的相对路径

修改完后,cp回pod再mc编译修改后的java文件,这里有个坑:不加-c,只执行mc 目录/xx.java -d 字节码的输出目录,会报错:

在这里插入图片描述

因为编译一个类可能需要其他import的类,此时可先查找下这个类的加载器的hash码:sc -d类全名

在这里插入图片描述

重新编译,这次mc加上 -c 类加载器的哈希码:

在这里插入图片描述

让类加载器重新加载新编译的字节码:

在这里插入图片描述

再jad反编译,看下是否修改成功:

在这里插入图片描述

合理!

3、注意点

注意点:

  • 这种方式只是将字节码信息更新到了内存中,程序重启,字节码还是会恢复成就的

  • 使用retransform,前面vi那步不能添加方法或字段

  • 如果你的方法正在被当前线程执行,那更新的动作也会失败

  • 所以,用阿尔萨斯热更新,只是一种应急的手段,比如CICD线出问题了,平时还是正常编译、打包、部署

文章来源:https://blog.csdn.net/llg___/article/details/135294646
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。