1.背景
对于Java游戏服务器来说,通常通过脚本运行jar执行。在开发测试环境下,需要经常打包、重新部署的需求,而往往重启服务器通常需要花费一定时间。而有了Spring-Loaded这个利器,直接替换运行的补丁jar,即可达到热更新功能.
2.说明
目前官网上的release版本:springloaded-1.2.3.RELEASE.jar,并不支持reload jar这个功能,这个功能在1.2.4才开放。不过你可以git clone下源代码,用gradle build最新的jar:springloaded-1.2.4.BUILD-SNAPSHOT.jar。不过这个版本可能些许问题,即对我们的"windoze"支持不太友好,这个问题已经和其作者联系过了,最新github上的代码应该修复了。我是本地自己修改了一下(具体怎么修改的,可以参见我的博客中和作者的几封邮件),然后build的。当然如果你是mac或者是linux运行,则会完美运行。
3.参数
-Dspringloaded=watchJars=foo.jar:bar.jar
即watchJars选项,监听的多个jar之前用:分离
4.例子
有两个jar,一个spring-load-main.jar,一个spring-load-extra.jar,前者依赖后者,后者业务可能会经常变化,有热更新的需求。这里模拟一下线上环境,用脚本启动进程(windows),然后修改逻辑,重新打包,替换jar,看是否可以达到reload的目的
1.启动脚本:spring-loaded-example_launch.bat
@echo off
cd/d%~dp0
java-noverify-javaagent:springloaded-1.2.4.BUILD-SNAPSHOT.jar-cp spring-load-main.jar;spring-load-extra.jar-Dspringloaded=verbose;explain;watchJars=spring-load-extra.jarcom.mavsplus.example.springloaded.SpringLoadedExample2说明:springloaded-1.2.4.BUILD-SNAPSHOT.jar/spring-load-main.jar/spring-load-extra.jar 这三个jar是在同一个目录."-javaagent"这个必须,指定agent为spring-loaded.通过-Dspringloaded=watchJars指定了监听的jar为spring-load-extra.jar
,main类为SpringLoadedExample2
2.spring-loaded-main.jar只有一个类SpringLoadedExample2,spring-loadex-extra.jar也只有一个类Reload
packagecom.mavsplus.example.springloaded;
importjava.util.concurrent.TimeUnit;
/*** **
* Spring Loaded allows you to add/modify/delete methods/fields/constructors.* The annotations on types/methods/fields/constructors* can also be modified and it is possible to add/remove/change values in enum types.***@authorlandon*@since1.8.0_25*/
public classSpringLoadedExample2 {
public static voidmain(String[] args)throwsException {
Reload reload= newReload();
while(true) {
reload.load();
TimeUnit.SECONDS.sleep(3);
}
}}
packagecom.mavsplus.example.springloaded;
/*** 可reload的实现类**@authorlandon*@since1.8.0_25*/
public classReload {
public voidload() {
System.out.println("load");
}
}
3.运行启动脚本:spring-loaded-example_launch.bat
E:\github\mavsplus-all\mavsplus-examples\src\main\resources>spring-loaded-exampl
e_launch.bat
SL: [verbose mode on] Full configuration is:verbose;explain;watchJars=spring-loa
d-extra.jar
SL: [explain mode on] Reporting on the decision making process within SpringLoad
ed
七月01,2015 8:25:16下午 org.springsource.loaded.agent.SpringLoadedPreProcesso
r logPreProcess
r logPreProcess
信息: SpringLoaded preprocessing: classname=java/util/concurrent/TimeUnit$7clas
sloader=nulltypeRegistry=null
load
load
load
load
4.修改Reload.java,输出reload,然后重新打一个包并覆盖掉spring-load-extra.jar,这时候看到命令行输出:
load
load
七月01,2015 8:28:51下午 org.springsource.loaded.agent.Watcher run
信息: Observed last modification time changefore:\github\mavsplus-all\mavsplus
-examples\src\main\resources\spring-load-extra.jar (lastScanTime=1435753730694)
七月01,2015 8:28:51下午 org.springsource.loaded.agent.Watcher determineChange
sSince
信息: Firing file changed event e:\github\mavsplus-all\mavsplus-examples\src\mai
n\resources\spring-load-extra.jar
七月01,2015 8:28:51下午 org.springsource.loaded.agent.SpringLoadedPreProcesso
r logPreProcess
信息: SpringLoaded preprocessing: classname=java/util/HashMap$KeyIterator classl
oader=nulltypeRegistry=null
信息: SpringLoaded preprocessing: classname=java/io/ObjectStreamClass$Caches cla
ssloader=nulltypeRegistry=null
reload
reload
reload
reload看上面红色部分,我们可以清楚的看到spring-loaded检测到了jar的时间戳的改变,并将其重新加载了,从输出我们可以看到
5.总结:
通过该例子我们可以清楚的看到,用spring-loaded简直太幸福了。。直接替换jar包。。直接更新。。完美
相对比JRebel还需要指定一个monitor jar class jar。。简单多了。。具体对比可以参考我的上一篇随笔: http://www.blogjava.net/landon/archive/2015/06/26/425909.html
后续:会深入源代码以及更深层次的例子而不仅仅是直接替换方法body形式的热加载。。进行深入剖析
posted on 2015-07-01 20:40 landon 阅读(7384) 评论(2) 编辑 收藏 所属分类: JVM 、HotSwap