远程热部署的落地实践

前言

​ 所谓热部署,就是在应用正在运行时升级软件,却不需要重新启动应用。对于 Java应用程序来说,热部署就是在运行时更新 Java 类文件,同时触发 Spring 以及其他常用第三方框架的一系列重新加载的过程。而在开发的过程中每天重启服务5-12次,单次3-8分钟,每天部署3-5次,部署频繁耗时长,严重影响上线的效率。而插件提供的本地和远程热部署功能,可让将代码变更“秒级”生效。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-73tglRvL-1682414554108)(C:\Users\202230236\AppData\Roaming\Typora\typora-user-images\image-20230425150819918.png)]

优势

​ 在使用热部署插件之后,开发者修改代码远程热部署能够秒级(2~10s)生效,开发者直接发起服务调用,可以节省大量的碎片化时间(热部署插件还具备流量回放、远程调用、远程反编译等功能,可配合进行使用)。

在这里插入图片描述

热部署的难点

​ 因为热部署不等同于热重启,像 Tomcat 或者 Spring Boot DevTools 此类热重启模式需要重新加载项目,性能较差增量热部署难度较大,需要兼容常用的中间件版本,需要深入启动销毁加载流程。另外需遵循四大原则。

在这里插入图片描述

可参照资料匮乏

字节码操作难度大

HOTSWAP限制

Spring源码复杂

兼容框架多

部署方式多

环境打通难

用户问题调试难

设计方案

架构设计

​ 插件由 4 大部分组成,包括脚本端、插件端、Agent 端,以及 服务端。脚本端负责自动化构建 Sonic 启动参数服务启动等集成工作IDEA 插件端集成环境为开发者提供更便捷的热部署服务Agent 端随项目启动负责热部署的功能实现服务端则负责收集热部署信息、失败上报等统计工作。如下图所示:

在这里插入图片描述

功能流转

​ 组件是通过 NIO 监听本地文件变更,触发文件变更事件,例如 Class 新增、Class修改、Spring Bean 重载等事件流程。下图展示了一次热部署单个文件的生命周期:

在这里插入图片描述

文件监听

​ 首先会在本地和远程预定义两个目录,/var/tmp/sonic/extraClasspath 和 /var/tmp/sonic/classes。extraClasspath 为 Sonic 自 定 义 的 拓 展Classpath URL,classes 为 Sonic 监听的目录,当有文件变更时,通过 IDEA 插件来部署到远程 / 本地,触发 Agent 的监听目录,来继续下面的热加载逻辑:

在这里插入图片描述

注意:

​ 因为考虑到业务方WAR 包的 API 项目、Spring Boot、Tomcat 项目、Jetty 项目等,都是以 JAR 包来启动的,这样是无法直接修改用户的 Class 文件的。即使是用户项目可以修改,直接操作用户的 Class,也会带来一系列的安全问题。所以,Sonic 采用拓展 ClassPath URL 路径来实现文件的修改和新增

​ 并且存在这么一种场景,多个业务侧的项目引入相同的 JAR 包,在 JAR 里面配置 MyBatis 的XML 和注解。在此类情况下,Sonic 没有办法直接来修改 JAR 包中源文件,通过拓展路径的方式可以不需要关注 JAR 包,来修改 JAR 包中某一文件和 XML。同理,采用此类方法可以进行整个 JAR 包的热替换。

在这里插入图片描述

JVM Class重载

​ JVM 的字节码批量重载逻辑,通过新的字节码二进制流和旧的 Class 对象生成ClassDefinition 定 义,instrumentation.redefineClasses(definitions), 来 触 发JVM 重载,重载过后将触发初始化时 Spring 插件注册的 Transfrom。

新增 class Sonic 如何保证可以加载到 Classloader 上下文中?由于项目在远程执行,所以运行环境复杂,有可能是 JAR 包方式启动(Spring Boot),也有可能是普通项目,也有可能是 War Web 项目,针对此类情况 Sonic 做了一层 ClassloaderURL 拓展

在这里插入图片描述

Spring Bean 重载

在这里插入图片描述

Spring XML重载

当用户修改 / 新增 Spring XML 时,需要对 XML 中所有 Bean 进行重载

重新 Reload 之后,将 Spring 销毁后重启。需要注意的是**:XML 修改方式改动较大,可能涉及到全局的 AOP 的配置以及前置和后置处理器相关的内容**,影响范围为全局,所以目前只放开普通的 XML Bean 标签的新增 / 修改,其他能力酌情逐步放开。

MyBatis 热部署

​ Spring MyBatis 热部署的主要处理流程是在启动期间获取所有 Configuration 路径,并维护它和 Spring Context 的对应关系在热部署 Class、XML 时去匹配Configuration,从而重新加载 Configuration 以达到热部署的目的

在这里插入图片描述

总结

​ 当前热部署主要是注重Spring Bean、Spring MVC、MyBatis 的重载流程。对于其他开发框架,需要更加深入了解底层实现,以达到兼容性。

补充说明

​ 此文只做博主了解热部署相关文档做的简单说明,该插件实现难度非常大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值