不停服热加载java代码

        我司自研的key-value数据库Xdb支持锁和事务,还是非常好用的,不过Xdb有一个问题就是死锁,尤其是频繁出现的死锁,基本上玩家啥都干不了了,只有重启.虽然程序员应该负责消灭所有死锁,但是这仅仅是理论上的可能.很多开发的task时间紧任务重,想要完美避免死锁很难. 不过xdb的这套体系也有两个优点:1逻辑和数据基本上是分离的,也就是说,不存在一个类即做逻辑又负责保存玩家数据;2 所有对数据的操作都通过Procedure来执行,而Procedure又有一个统一的入口方法Process.这使得热替换一个Procedure成为了可能.

下面演示一下怎么写一个新的Procedure替换旧的,并在服务器开着的情况下加载执行:

1.比如常用的加经验Procedure PAddExpProc,我想新写一个PAddExpProc2,来在线替换之前的PAddExpProc,第一步自然是新建一个Procedure的子类PAddExpProc2:

不停服热加载java代码

注意PAddExpProc2类的构造函数跟之前的PAddExpProc不一样,因为每个Procedure的子类的构造函数的参数个数和类型都是不一样的,没有办法统一,比较好的办法就是把旧的PAddExpProc的实例传进来,然后新类自己初始化需要的参数.比如PAddExpProc2需要5个参数,这5个参数都可以通过反射从原来的procedure里面拿到:

不停服热加载java代码

2.然后开始打包写好的类,可以自己用命令打,也可以用eclipse的输出功能,最后打好的jar包取名为hotdeploy.jar.这个jar的名字是在sys.properties文件中的sys.hotdeploy.jarfile属性配置的.

3.接下来是怎么把jar包部署到外网上去.为了方便,没有搞一个新的流程,而是借用了已有的reload机制,通过xml指定要热加载的类,然后读取xml来实现类的热加载.

    3.1修改knight.gsp.main.HotfixConfig.xml文件,指定我们要加载的是哪个xml:

不停服热加载java代码

    这一步也可以不手写,通过修改f服务器热加载配置.xlsx,并打表提交文件来实现

    3.2然后就是修改knight.gsp.SystemSetting.SHotdeployClass.xml文件,把要替换的新类名和老类名写上:

    

不停服热加载java代码

这一步也可以不手写,通过修改f服务器热加载配置Proc.xlsx并打表提交文件来实现:

不停服热加载java代码

4.前面三步都完成之后就可以把jar包和那两个xml文件同步到服务器上(hotdeploy.jar是跟gsxdb.jar同目录的),执行reload脚本,

reload脚本会启动新类的加载:

4.1先写一个ClassLoader的子类:

不停服热加载java代码

 核心代码就是把jar包里的class都加载:

不停服热加载java代码

4.2 这些加载的类都放入map中,并且设置标志位,这样不用每次都判断map是否empty:

不停服热加载java代码

4.3当procedure真正执行的时候,先判断是否有新加载的类,如果有,优先执行新加载的:

不停服热加载java代码