天天看點

Java項目有可能做到所有的代碼邏輯均可熱部署嗎?

作者:Java碼農之路

前言

首先我們明确下什麼叫做熱部署,熱部署是在不重新開機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項目有可能做到所有的代碼邏輯均可熱部署嗎?

這種模式的好處就是,不需要熱更新的部分可以用java元件來寫,需要經常變的部分可以用腳本來寫。所有的元件均可混搭成為一個業務。如何編排這些元件,LiteFlow獨創了ELF文法,擁有非常好上手的編排文法。程式員的話,十分鐘就可以上手。上圖粉色部分就是最簡單的一種串聯形式。

業務鍊路中元件可實時更換,也可實時增加,形成一個新的業務鍊。同時定義好的元件也可複用在其他的鍊路中。

Java項目有可能做到所有的代碼邏輯均可熱部署嗎?

LiteFlow的腳本方案也是利用JSR223來實作的,目前已經實作的腳本有三種:

Java項目有可能做到所有的代碼邏輯均可熱部署嗎?

為什麼說利用LiteFlow編排引擎架構,你的所有邏輯都是可以變更的呢。因為你完全可以把所有的邏輯都用腳本元件來實作,LiteFlow提供了非常強大的腳本支援,完全和Java底層打通,你可以在腳本中import java的類,也可以調用java的類方法,甚至于可以在腳本中去定義方法,定義類,一切寫法和java中完全一樣。

更誇張的是,LiteFlow允許你在腳本中調用spring上下文的bean,你可以在腳本中調用DAO取資料,可以在腳本中發送rpc給其他微服務。隻要你願意,你可以一行java業務代碼不寫,完全把業務搬到腳本元件中去。

而且連邏輯塊的順序你也可以随意變動,因為LiteFlow的編排規則和腳本均可實作熱變更。

LiteFlow為經常用的存儲中間件也提供了原生支援:

Java項目有可能做到所有的代碼邏輯均可熱部署嗎?

LiteFlow支援所有的關系型資料庫,另外zk,etcd,nacos均可支援,還提供了額外的擴充接口,供你自己擴充成其他的存儲方式。

有想過麼,你所有的邏輯和規則編排文法,都是存在于系統之外的。隻要更改其腳本和邏輯,你所有節點的系統不需要做任何事,實時的進行熱變更。

而這一切,LiteFlow做到了非常平滑,所謂平滑的意思是,不用擔心在熱變更的時候你的業務會受到任何的中斷,也不會因為熱變更造成正在執行的鍊路産生任何的異常。

LiteFlow編排能力有多強大呢,簡單的幾個關鍵字就可以編排出超乎想象的效果:

Java項目有可能做到所有的代碼邏輯均可熱部署嗎?
Java項目有可能做到所有的代碼邏輯均可熱部署嗎?

結語

在java的業務熱部署領域,LiteFlow作為一款規則引擎,給出了一種新的解決思路。

除以上文中介紹的之外,LiteFlow架構還擁有衆多的進階特性,從各個方位提升你系統的靈活性。

并且作為開源軟體,LiteFlow擁有國内非常好的社群氛圍和文化。

繼續閱讀