利用springloaded進行java jar&class的動態替換


之前已經寫過一篇關於class的動態替換博客,今天我們來介紹一下如何用springloaded進行jar&class的動態替換。

首先說一下實驗過程,結合了目前我正在做的項目,這個項目是一個前置系統,分別對接銀聯和核心系統。項目一開始由一個jar包組成,邏輯上可以分為3層:分發層,業務處理層,dao層(數據庫操作相關),所有的class文件最后都在jar包中,運行時,只要啟動這個jar包就行了,它是一個進程,會啟動一個監聽端口用來接收銀聯發送過來的報文。

這樣做的缺點:后期你要修改代碼,哪怕只有一行代碼修改,你也要重新打包成jar包,kill掉正在運行的進程,然后重新啟動!一開始對於我這種菜鳥,除了覺得這樣做很麻煩之外,其他也沒有覺得什么。后來,仔細一分析,在生產上運行,你停服務,是一件不可思議的事,因為所有的交易都要停止,像對於支付這樣的交易,那影響就太大了!

所以,自然想到熱部署方案,熱部署網上也有一些相關的博客。但基本都不太“正規”,即都是那種簡單的例子,看起來就不大可行。其中比較多的是自己定義classload來重新加載class文件,而且我看那些方法中路徑和要重新加載的class文件都是寫死的,這也太。。。當然,也有我覺得比較高大上的方法,就是將現在的系統改造成微服務架構,對於業務上獨立的交易都改造成一個個微服務,那要卸載服務,重新部署服務自然都不在話下。不得不說,這確實是一個比較好的方法,但工作量和難度都是比較高的,想來想去,暫時不考慮,但會作為知識儲備來學習,在適當的時間再來改造,因為這是趨勢!

直到前幾天,我偶然發現一個關於springloaded的帖子,這種方法比較簡單,而且從名字可以看成,它是spring旗下的一個項目,應該來說還是比較可靠的,所以就試着用這個方法來進行改造,改造的方法也比較簡單。

首先,我們要將jar包中的一些業務相關的代碼從jar包中抽離出來,具體拆分的方法可以為,基本不需要修改的代碼或者框架型的代碼放在jar包中,而后期需要經常修改的代碼從jar包沖分離出來。如下圖:

所有的業務相關的代碼(class文件)都放在business文件夾下,具體做法是創建了一個新的工程,然后現有的工程會依賴這個新的工程。同時,可以看到相關的配置文件我們也從jar包中分離出來,比如mybatis文件夾中放的是和數據庫操作相關的文件。

我們在libs文件夾中放入

然后,輸入命令:

這里插播一下,一開始我是上面這種寫法,但是發現jar替換時不起任何效果,后來我想會不會是順序的問題,我把-jar后面的參數移到最后面,發現這時候起作用了:

然后參數verbose可以省略,因為加上這個參數,日志中會有很多詳細的信息,生產上不太方便查看,測試的時候可以加上。

我們發起一筆報文,前置系統運行結果如下:

我們對這個交易的代碼進行修改,把“協議支付簽約觸發短信”這幾個字去掉,然后保存,用這個class文件替換原先的class文件

可以看到,在不用停程序的情況下,運行結果已經改變了,基本達到我們的需求。

接下來的話就是,如果jar包里面的代碼有修改,那就重新打包來替換舊的jar包,與替換class文件類似,我試了一下,同樣是可以的。

 

2018-07-25更新

今天我在生產上試了一種情況,發現更換了class沒有用,比如:a.jar直接調用了b.class,而b.class又調用了c.class,現在替換了c.class文件,發現不起作用。我們上面的例子是替換了b.class文件起作用。只有重啟,c.class文件才起作用。這個問題后續值得繼續關注!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM