java 热部署 自动加载 更新 jar包

java 热部署 自动加载 更新 jar包

之前博主公司有一个需求,就是系统升级的时候不要影响生产环境的运行,不能重新启动服务器。后来经过博主的不断探索也是实现了这样的功能。博主在网络上面也是找了好多资料,发现有用的东西很少,基本没有什么帮助。那么博主就打算把自己的经验分享出来。

博主的设计思路是 破坏java的双亲委派模型,自己实现bean容器,监听服务器系统目录,实时更新bean容器中的对象
  • 双亲委派模型
    双亲委派模型是什么?是java加载类进入虚拟机时的一种加载策略。我们都知道类是由类加载器加载的,但是类加载器并不是只有一个,而是有多个,如果你看过源码的话,一定会发现在类加载器中,每次加载类都会向它的父类询问是否加载过了,并依次向上,如果加载过了就不再重新记载(这里是重点!),如果没有加载,就进行加载!

  • 问题所在
    知道了什么是双亲委派,问题就出来了,我们要进行热部署,热更新。其实就是为了更新内存中的字节码,但是在加载类的时候,虚拟机会发现你的类还是那个类(并没有校验具体内容是否改变),所以不会重新加载。进而无法实现字节码的替换!
    知道问题了,我们该如何解决呢?首先就是要破坏这个双亲委派模型,我们要强制性的加载类,也就是说,只要我们想重新加载,它就必须去加载,那么我们就要自己写一个classloader,并使用我们的classloader去进行加载!
    核心问题通过上一种思路就可以解决,但是!光能加载还不够,就像造一辆汽车,现在有了发动机,可是你还没有轮子,方向盘,变速箱,要求高点,你还想要个车棚,真皮座椅呢!

思路

破坏双亲,自己做主

  • 破坏双亲委派模型,可以不受限制的加载字节码进内存。

谁要加载?配置决定

  • 我们既然要更新,肯定是有一些特定的类要进行更新,这里我也是建议,可以发生拼接功能的代码独自封包,方便管理,并且要使用一些设计模式来增加代码的灵活性,其中策略模式,模板模式,责任链模式都有良好表现。
    所谓配置决定,是希望你能通过配置文件,告诉程序,你要加载哪些类,要对哪些类进行特殊的初值等。

左手IOC,右手DI

  • 如何把加载的字节码转成对象呢,这里就需要配合上步的配置,通过读取配置文件,生成对象,并完成依赖注入,博主这里也是参考spring。

bean容器,要跟上

  • 那么有一个问题,现在spring在java中真的是随处可见了,现在我们创建业务对象基本都是使用注解或者配置文件,交由spring去生成,这里就会有一个棘手的问题,交由spring处理,那么类加载器就是spring的,不是你自己的!这里很重要,你就无法继续完成热加载了!
  • 所以,这个对象的创建一定要由我们自己去创建,那么接下来就有2中思路
    • 创建好的对象放到spring容器中
    • 自己维护一个容器,需要热加载的对象都在这个容器中进行管理

博主是倾向第二种的

触发难?监视器来帮忙

如果上面的问题,你都顺利解决了,那么恭喜你,基本上这个车子可以跑起来了,但是跑的好不好,还要你自行判断。
接下来我要给他加点装饰品。

在升级过程中,我们肯定是要上传jar包的,jar包上传后才能重新加载,否则报错都是很正常的现象
那么如何能让他自动触发升级,只要它检测到了jar包有变化就执行加载呢?

  • watchservice 没错就是用它,我们无需考虑是win还是linux,它会自动判断。他的工作原理是,和操作系统进行联动,监视某一个目录的状态,如果目录增加了,更改了,或者是删除了,watchservice都会收到操作系统给的通知,那么这个时候我们就可以针对这个目录的不同变化采取不同的操作。(说到这里,你是否已经有些思路了呢)

需要注意的是,watchservice在目录刚刚发生变化时就会被触发。所以一定要等待上传完成才去操作!

太佩服我这文采了,给自己跪了
嗯~ o( ̄▽ ̄)o 理论大概就是这些,博主还在苦逼出差,示例代码后续再写了

由于博主正在出差,内容正在施工,有需要的小伙伴可以先在下面留言占个位置。博主一有时间就会更新文章的!
Last modification:December 2nd, 2019 at 11:16 am
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment

召唤看板娘