前言
首先我們明確下什么叫做熱部署,熱部署是在不重啟java虛擬機的前提下,自動更新class的行為,從而更新整個運行時的邏輯。
在java開發領域,熱部署一直是一個難以解決的問題,java虛擬機理論上只能實現方法體的修改熱部署,對于整個類結構的更改,仍然需要重啟虛擬機,對類重新加載才能完成更新操作。
OSGI
其實java業界有一些解決方案,比如osgi架構,這玩意時間比較長了,但一直沒火起來。osgi架構的出現,可以讓java系統變成模塊化的形式,讓模塊重啟成為可能。從一定程度上也算是個熱部署的方案??上н@玩意以前開發起來就覺得很反人類,配置文件一大堆不說,學習成本也很大。和spring結合起來,居然是一個模塊一個spring上下文體系。并且如果模塊之間有調用關系的話,重啟相關的模塊會讓應用出現短暫的功能性休克,也就說,整個熱啟動過程不平滑。
這項技術現在估計很多小伙伴都沒聽說過,目前也漸漸的退出歷史舞臺,用的企業估計很少。
ASM
ASM是一款修改字節碼的框架,同類型的框架還有Cglib。這些框架能加載一個class信息,用戶可以按照自己的需求增強修改這些信息,最后輸出成一個新的class。
具體實現過程,這里就不展開了。大家可以百度下,相關技術實現文章不少。
但單純修改字節碼一般要和其他技術結合起來,單靠這個也無法完成熱更新,雖然ASM類的框架能夠修改類,但是這些ASM的修改邏輯也是用java寫的,這段代碼也需要執行的。如果你把ASM的代碼寫在java里,也無法實現從外部
來熱更新。
Javaagent&Attach API結合ASM
這就是上面一段說的ASM要結合其他技術才能實現熱更新的方案,也是目前很多開源框架采用的方案。
比如大名鼎鼎的Arthas,就是利用javaagent通過Attach API運行時加載目標Java程序,最終利用Instrumention API或者ASM增強class,來實現代碼跟蹤,以及代碼熱修改的特性。
但筆者認為用Arthas來完成線上代碼的熱更新,只能用于一些很緊急的場景。不能替代日常業務邏輯修改。而且操作起來也挺復雜。
你需要先修改java代碼,然后把java代碼放到服務器上,在arthas里查找這個類的類加載器的hashcode,然后利用arthas提供的命令編譯java代碼輸出成新的class文件,最用利用redefine
命令進行熱更新。
試想下,如果大量邏輯的更改。這得有多麻煩。
所以更多的是利用arthas對線上應用進行診斷,追蹤,熱更改代碼其實就是arthas眾多功能中其中一個,并不是主要功能。
換一種思路
以上方案都是基于修改class本身,然后讓JVM的類加載器重新加載來實現的。
那么有沒有更好的方案呢?
其實java代碼可以運行一些腳本的,jdk本身就支持調用腳本,從JDK 1.6開始,java就支持JSR223,可以用一致的形式在JVM上執行一些腳本語言,而且可實時編譯,運行的效率和java不相上下的。
有的同學看到這里可能會拍磚了:利用腳本只能更改部分邏輯,不可能把所有的邏輯都用腳本寫吧,你這篇文章探討的不是“有沒有可能所有的邏輯
都可熱更新”么?
別急,首先我們來確定一個事情。你的java應用系統需不需要所有的
邏輯都是可以熱更新的?很多代碼都是大致固定不變的,比如util類,一些vo的定義也不大變更的,一些固定的業務也不需要熱更新需求的。只有一些經常變更的決策部分,可能需要熱更新。
那么我們只要把需要經常變的部分用腳本來定義不就可以了么。
業界有沒有類似的開源框架呢?
還真有,而且是高star的熱門開源項目,能夠幫你做到用腳本進行熱更新業務。
開源編排規則引擎
可能有小伙伴又要說了:你不是介紹java代碼熱部署么,怎么話題轉到規則引擎上去了?
這里要說下,規則引擎的一大特性就是把決策部分邏輯剝離到外面,能夠實現邏輯的變動快速熱變更。
而這次介紹的規則引擎框架則更為強大,除了能剝離邏輯,還能解耦系統,讓你的所有的邏輯塊均可隨意變更。理論上能實現所有
的邏輯都可變更,不是部分
哦。
這就是業界現在 很火的編排式規則引擎框架:LiteFlow
。
LiteFlow的理念很簡單,就是把系統中的各個邏輯切分成一小塊一小塊的,稱之為組件
,這些組件可以由java代碼來寫,也可以用腳本來寫。然后一個完整業務就是把各個組件組搭一起,形成一個完整業務鏈。
這種模式的好處就是,不需要熱更新的部分可以用java組件來寫,需要經常變的部分可以用腳本來寫。所有的組件均可混搭成為一個業務。如何編排這些組件,LiteFlow獨創了ELF語法,擁有非常好上手的編排語法。程序員的話,十分鐘就可以上手。上圖粉色部分就是最簡單的一種串聯形式。
業務鏈路中組件可實時更換,也可實時增加,形成一個新的業務鏈。同時定義好的組件也可復用在其他的鏈路中。
LiteFlow的腳本方案也是利用JSR223來實現的,目前已經實現的腳本有三種:
為什么說利用LiteFlow編排引擎框架,你的所有邏輯都是可以變更的呢。因為你完全可以把所有的邏輯都用腳本組件來實現,LiteFlow提供了非常強大的腳本支持,完全和Java底層打通,你可以在腳本中import java的類,也可以調用java的類方法,甚至于可以在腳本中去定義方法,定義類,一切寫法和java中完全一樣。
更夸張的是,LiteFlow允許你在腳本中調用spring上下文的bean,你可以在腳本中調用DAO取數據,可以在腳本中發送rpc給其他微服務。只要你愿意,你可以一行java業務代碼不寫,完全把業務搬到腳本組件中去。
而且連邏輯塊的順序你也可以隨意變動,因為LiteFlow的編排規則和腳本均可實現熱變更。
LiteFlow為經常用的存儲中間件也提供了原生支持:
LiteFlow支持所有的關系型數據庫,另外zk,etcd,nacos均可支持,還提供了額外的擴展接口,供你自己擴展成其他的存儲方式。
有想過么,你所有的邏輯和規則編排語法,都是存在于系統之外的。只要更改其腳本和邏輯,你所有節點的系統不需要做任何事,實時的進行熱變更。
而這一切,LiteFlow做到了非常平滑,所謂平滑的意思是,不用擔心在熱變更的時候你的業務會受到任何的中斷,也不會因為熱變更造成正在執行的鏈路產生任何的異常。
LiteFlow編排能力有多強大呢,簡單的幾個關鍵字就可以編排出超乎想象的效果:
結語
在java的業務熱部署領域,LiteFlow作為一款規則引擎,給出了一種新的解決思路。
除以上文中介紹的之外,LiteFlow框架還擁有眾多的高級特性,從各個方位提升你系統的靈活性。
并且作為開源軟件,LiteFlow擁有國內非常好的社區氛圍和文化。
最后放出LiteFlow的官網和倉庫地址,如果你覺得這款開源框架對你的業務有幫助,趕緊來了解一下吧
項目官網:
gitee托管倉庫:
https://gitee.com/dromara/liteFlow
github托管倉庫: