I want to fly higher
programming Explorer
posts - 114,comments - 263,trackbacks - 0
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 /%~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.jar com.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

package com.mavsplus.example.springloaded;

import java.util.concurrent.TimeUnit;

/**
 * <a href="https://github.com/spring-projects/spring-loaded"></a>
 * 
 * <pre>
 *     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.
 * </pre>
 * 
 * @author landon
 * @since 1.8.0_25
 
*/
public class SpringLoadedExample2 {

    public static void main(String[] args) throws Exception {
        Reload reload = new Reload();

        while (true) {
            reload.load();

            TimeUnit.SECONDS.sleep(3);
        }
    }
}  

package com.mavsplus.example.springloaded;

/**
 * 可reload的实现类
 * 
 * @author landon
 * @since 1.8.0_25
 
*/
public class Reload {

    public void load() {
        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
七月 012015 8:25:16 下午 org.springsource.loaded.agent.SpringLoadedPreProcesso
r logPreProcess



r logPreProcess
信息: SpringLoaded preprocessing: classname=java/util/concurrent/TimeUnit$7 clas
sloader=null typeRegistry=null
load
load
load
load

   4.修改Reload.java,输出reload,然后重新打一个包并覆盖掉spring-load-extra.jar,这时候看到命令行输出:

load
load
七月 012015 8:28:51 下午 org.springsource.loaded.agent.Watcher run
信息: Observed last modification time change for e:\github\mavsplus-all\mavsplus
-examples\src\main\resources\spring-load-extra.jar (lastScanTime=1435753730694)
七月 012015 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
七月 012015 8:28:51 下午 org.springsource.loaded.agent.SpringLoadedPreProcesso
r logPreProcess
信息: SpringLoaded preprocessing: classname=java/util/HashMap$KeyIterator classl
oader=null typeRegistry=null



信息: SpringLoaded preprocessing: classname=java/io/ObjectStreamClass$Caches cla
ssloader=null typeRegistry=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 阅读(7724) 评论(2)  编辑  收藏 所属分类: JVMHotSwap

FeedBack:
# re: Spring-Loaded 使用Ⅱ-Reload Jar
2015-09-15 15:23 | 赵辉
貌似1.2.4也没开放  回复  更多评论
  
# re: Spring-Loaded 使用Ⅱ-Reload Jar
2015-10-05 23:01 | landon
@赵辉
我没有用1.2.4,直接自己build的代码并修改了对于windows的一个小的bug。
你可以查看一下1.2.4相关代码。TypeRegistry#couldBeReloadable,是否fixed了对于windows的支持。 int lastSlashPos = slashedName.lastIndexOf(File.separator);  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: