1. 前言
本文主要介绍Java远程热部署插件HotSeconds的使用,HotSeconds分为HotSecondsClient和HotSecondsServer,HotSecondsClient是IDEA插件,可以在插件市场下载,HotSecondsServer是服务端javaagent插件,主要实现对服务端的热部署。
2. 功能介绍
2.1 插件安装
HotSecondsServer安装
github.com/thanple/Hot...
HotSecondsClient安装
在Plugins->Marketplace中搜索HotSecondsClient,下载安装即可
安装完后可以看到三个区域,工具栏(Debug旁边),Run菜单栏和HotSecondsClient控制台
HotSecondsClient控制台的有所有的菜单功能,所以后面以HotSecondsClient控制台为准进行介绍。
IDEA最新版的UI在Debug旁边看不到按钮了,HotSecondsClient控制台和Run菜单都是有的。
2.2 连接远程服务器
点击HotSecondsClient控制台->HotSeconds Settings->Settings,弹出配置框,可以配置远程ip,端口和路径映射
路径映射(Path mappings)
- class: 可以不用配置,默认上传到服务器的remote_src目录
- 资源文件: 需要配置本地哪些文件上传到服务器的哪个目录
- jar包:需要配置,服务器检测到jar包上传时会热加载每个class
配置完之后,点击Start HotSeconds连接远程服务器,连接成功之后,会出现批量热部署的按钮。
2.3 单文件热更新
2.3.1 java文件热更新
在打开的java文件上右键,选中 Hot swap this file to remote,会先编译,编译完后会将class文件(包括内部类)热更新到远程服务器
如果没有语法错误,但是遇到编译失败,可以先Build一下工程,再试一下热更新。
2.3.2 资源文件热更新
在资源文件上右键也可以选择 Hot swap this file to remote,那么资源文件是怎么实现热部署的呢? 这里是根据Path mappings中的路径映射,将本地的资源文件热部署到远程对应目录
但是资源文件非常复杂,比如xml ,html, css, js,properties等等文件,框架也非常的多,又是怎么实现热部署的呢?
路径映射只是将文件上传到服务器端,真正生效的是上传完之后刷新资源文件的缓存的逻辑,这就涉及到插件扩展,本插件内核集成了MyBatis和MyBatis Plus的xml的热更新,更多的资源文件热更新,详见插件扩展。
2.3.3 jar包热更新
在打开的jar上面右键,可以看到两个选项,Hot deploy the Jar to remote 和 Hot swao this file to remote。
前者是将整个jar的所有class热部署的服务器,后者只热更新选中的class。
2.3.4 远程编译并热部署
在java文件上右键选中 Hot swap this file to remote,会在本地编译然后热更新到远程,但是有的时候本地编译并不方便,比如本地和远程服务器的JDK版本可能存在巨大的差异,这个时候就需要远程编译了。
在java文件上右键,选择Remote compilation and hot swap 可以在远端编译并热更新。
2.4 批量热部署
点击HotSecondsClient控制台上的批量热部署按钮,弹出批量热部署修改的文件的面板,可以将修改的文件批量热部署到远程。
其中resource同2.3.2,也是需要配置Path mappings。
2.5 自动热部署
在配置框中选中Auto deployment,只要修改了资源文件并保存,就可以将资源文件自动热部署到远程服务器。
2.6 远程执行函数
在静态无参函数上,右键,选择Run method on remote server,可以在远程服务器上触发这个函数并返回到本地控制台,如果是对象会转换成json字符串。
那么如果是非静态,或者有参数的方法该如何调用呢?
可以写一个静态无参函数,然后调用需要的函数就行了,改完代码先远程热部署,再远程执行函数,针对查看内存变量和在沙箱环境下修复线上数据,是非常方便的。
这样就不用写接口,不用http请求,也不用调rpc请求,直接就能触发需要的代码,可谓是将远程服务器拿捏在股掌之间。
2.7 插件扩展
前面提到资源文件上传完以后,该如何扩展自定义的刷新缓存的逻辑呢?
其实不管是java文件还是资源文件,服务器安装包里面提供了一个IHotExtHandler文件,拷贝到工程里面,实现这个接口,然后配置到hot-seconds-remote.xml就行了。
IHotExtHandler接口有两个函数,preHandle和afterHandle,前者是同步执行,后者是异步执行的。
void preHandle(ClassLoader classLoader, String path, byte[] content);
void afterHandle(ClassLoader classLoader, Class<?> classz, String path, byte[] content);
更多的框架支持详见扩展项目: github.com/Liubsyy/Hot...
项目在不断的更新和完善中
2.8 多语言支持
设置里面可以选择多语言支持
2.9 多IP支持
远程服务端机器比较多,可以添加和管理IP,这样不用来回改IP。
3.支持范围
3.1 插件内核支持范围
开源组件 | 范围 |
---|---|
Java | 修改代码,新增字段,新增方法,新增类,修改动态代理类 |
Spring | 包括Spring,SpringMVC,SpringBoot生态 |
MyBatis | 支持mapper修改xml文件(扩展包HotSecondsExtension已支持新增mapper和xml) |
MyBatis Plus | 同MyBatis |
Freemarker Thymeleaf Velocity-Spring | 刷新缓存 |
更多的组件/框架热更新请关注扩展开源项目HotSecondsExtension
3.2 支持环境
本插件支持本地热部署,以及远程热部署(测试和沙箱环境),线上不推荐用本插件进行热部署。
为什么不推荐线上用热部署呢?
Java和普通脚本语言不一样,运行的字节码已经加载到内存里了,如果线上一边运行运行高并发程序,一边还要热更新会对性能造成很大的影响,无异于轰炸机一边轰炸,一边还要加油。另外一点就是,没有哪个IDE是直接连接线上热部署的,这样很不安全,生产环境一定是越简单越安全。
那么线上该如何热更新呢?
线上使用热更新一般是热修复问题,可以直接用Java底层的Instrument机制实现类的替换,不过这样只能修改代码块,不能修改/新增字段和方法。
成熟一点的开源工具可以用arthas,底层也是基于Instrument API,不能修改/新增字段和方法。
4.未来
- 不断更新和完善新框架和市面流行框架的热部署,把扩展包做成一个新的项目
- 目前支持Java8 版本,过段时间支持下更高版本的JDK的热部署,比如Java11、Java17
- 插件增加一些实用的功能,类似于远程执行函数这种功能(已经实现),欢迎大家给出建议
- 扩展插件到其他的编程语言和IDE