0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

OSC開源社區(qū) ? 來源: OSCHINA 社區(qū) ? 作者:鉑賽東 ? 2022-11-23 11:47 ? 次閱讀

前言

首先我們明確下什么叫做熱部署,熱部署是在不重啟 java 虛擬機的前提下,自動更新 class 的行為,從而更新整個運行時的邏輯。 在 java 開發(fā)領(lǐng)域,熱部署一直是一個難以解決的問題,java 虛擬機理論上只能實現(xiàn)方法體的修改熱部署,對于整個類結(jié)構(gòu)的更改,仍然需要重啟虛擬機,對類重新加載才能完成更新操作。

OSGI

其實 java 業(yè)界有一些解決方案,比如 osgi 架構(gòu),這玩意時間比較長了,但一直沒火起來。osgi 架構(gòu)的出現(xiàn),可以讓 java 系統(tǒng)變成模塊化的形式,讓模塊重啟成為可能。從一定程度上也算是個熱部署的方案??上н@玩意以前開發(fā)起來就覺得很反人類,配置文件一大堆不說,學習成本也很大。和 spring 結(jié)合起來,居然是一個模塊一個 spring 上下文體系。并且如果模塊之間有調(diào)用關(guān)系的話,重啟相關(guān)的模塊會讓應(yīng)用出現(xiàn)短暫的功能性休克,也就說,整個熱啟動過程不平滑。 這項技術(shù)現(xiàn)在估計很多小伙伴都沒聽說過,目前也漸漸的退出歷史舞臺,用的企業(yè)估計很少。

ASM

ASM 是一款修改字節(jié)碼的框架,同類型的框架還有 Cglib。這些框架能加載一個 class 信息,用戶可以按照自己的需求增強修改這些信息,最后輸出成一個新的 class。 具體實現(xiàn)過程,這里就不展開了。大家可以百度下,相關(guān)技術(shù)實現(xiàn)文章不少。 但單純修改字節(jié)碼一般要和其他技術(shù)結(jié)合起來,單靠這個也無法完成熱更新,雖然 ASM 類的框架能夠修改類,但是這些 ASM 的修改邏輯也是用 java 寫的,這段代碼也需要執(zhí)行的。如果你把 ASM 的代碼寫在 java 里,也無法實現(xiàn)從外部來熱更新。

Javaagent&Attach API 結(jié)合 ASM

這就是上面一段說的 ASM 要結(jié)合其他技術(shù)才能實現(xiàn)熱更新的方案,也是目前很多開源框架采用的方案。 比如大名鼎鼎的 Arthas,就是利用 javaagent 通過 Attach API 運行時加載目標 Java 程序,最終利用 Instrumention API 或者 ASM 增強 class,來實現(xiàn)代碼跟蹤,以及代碼熱修改的特性。 但筆者認為用 Arthas 來完成線上代碼的熱更新,只能用于一些很緊急的場景。不能替代日常業(yè)務(wù)邏輯修改。而且操作起來也挺復雜。 你需要先修改 java 代碼,然后把 java 代碼放到服務(wù)器上,在 arthas 里查找這個類的類加載器的 hashcode,然后利用 arthas 提供的命令編譯 java 代碼輸出成新的 class 文件,最用利用redefine命令進行熱更新。 試想下,如果大量邏輯的更改。這得有多麻煩。 所以更多的是利用 arthas 對線上應(yīng)用進行診斷,追蹤,熱更改代碼其實就是 arthas 眾多功能中其中一個,并不是主要功能。

換一種思路

以上方案都是基于修改 class 本身,然后讓 JVM 的類加載器重新加載來實現(xiàn)的。 那么有沒有更好的方案呢? 其實 java 代碼可以運行一些腳本的,jdk 本身就支持調(diào)用腳本,從 JDK 1.6 開始,java 就支持 JSR223,可以用一致的形式在 JVM 上執(zhí)行一些腳本語言,而且可實時編譯,運行的效率和 java 不相上下的。 有的同學看到這里可能會拍磚了:利用腳本只能更改部分邏輯,不可能把所有的邏輯都用腳本寫吧,你這篇文章探討的不是 “有沒有可能所有的邏輯都可熱更新” 么? 別急,首先我們來確定一個事情。你的 java 應(yīng)用系統(tǒng)需不需要所有的邏輯都是可以熱更新的?很多代碼都是大致固定不變的,比如 util 類,一些 vo 的定義也不大變更的,一些固定的業(yè)務(wù)也不需要熱更新需求的。只有一些經(jīng)常變更的決策部分,可能需要熱更新。 那么我們只要把需要經(jīng)常變的部分用腳本來定義不就可以了么。 業(yè)界有沒有類似的開源框架呢? 還真有,而且是高 star 的熱門開源項目,能夠幫你做到用腳本進行熱更新業(yè)務(wù)。

開源編排規(guī)則引擎

可能有小伙伴又要說了:你不是介紹 java 代碼熱部署么,怎么話題轉(zhuǎn)到規(guī)則引擎上去了? 這里要說下,規(guī)則引擎的一大特性就是把決策部分邏輯剝離到外面,能夠?qū)崿F(xiàn)邏輯的變動快速熱變更。 而這次介紹的規(guī)則引擎框架則更為強大,除了能剝離邏輯,還能解耦系統(tǒng),讓你的所有的邏輯塊均可隨意變更。理論上能實現(xiàn)所有的邏輯都可變更,不是部分哦。 這就是業(yè)界現(xiàn)在 很火的編排式規(guī)則引擎框架:LiteFlow。 LiteFlow 的理念很簡單,就是把系統(tǒng)中的各個邏輯切分成一小塊一小塊的,稱之為組件,這些組件可以由 java 代碼來寫,也可以用腳本來寫。然后一個完整業(yè)務(wù)就是把各個組件組搭一起,形成一個完整業(yè)務(wù)鏈。

3c90e9e4-667d-11ed-8abf-dac502259ad0.png


這種模式的好處就是,不需要熱更新的部分可以用 java 組件來寫,需要經(jīng)常變的部分可以用腳本來寫。所有的組件均可混搭成為一個業(yè)務(wù)。如何編排這些組件,LiteFlow 獨創(chuàng)了 ELF 語法,擁有非常好上手的編排語法。程序員的話,十分鐘就可以上手。上圖粉色部分就是最簡單的一種串聯(lián)形式。 業(yè)務(wù)鏈路中組件可實時更換,也可實時增加,形成一個新的業(yè)務(wù)鏈。同時定義好的組件也可復用在其他的鏈路中。

3cb80c68-667d-11ed-8abf-dac502259ad0.png


LiteFlow 的腳本方案也是利用 JSR223 來實現(xiàn)的,目前已經(jīng)實現(xiàn)的腳本有三種:

3ce1f2c6-667d-11ed-8abf-dac502259ad0.png


為什么說利用 LiteFlow 編排引擎框架,你的所有邏輯都是可以變更的呢。因為你完全可以把所有的邏輯都用腳本組件來實現(xiàn),LiteFlow 提供了非常強大的腳本支持,完全和 Java 底層打通,你可以在腳本中 import java 的類,也可以調(diào)用 java 的類方法,甚至于可以在腳本中去定義方法,定義類,一切寫法和 java 中完全一樣。 更夸張的是,LiteFlow 允許你在腳本中調(diào)用 spring 上下文的 bean,你可以在腳本中調(diào)用 DAO 取數(shù)據(jù),可以在腳本中發(fā)送 rpc 給其他微服務(wù)。只要你愿意,你可以一行 java 業(yè)務(wù)代碼不寫,完全把業(yè)務(wù)搬到腳本組件中去。 而且連邏輯塊的順序你也可以隨意變動,因為 LiteFlow 的編排規(guī)則和腳本均可實現(xiàn)熱變更。 LiteFlow 為經(jīng)常用的存儲中間件也提供了原生支持:

3d196af8-667d-11ed-8abf-dac502259ad0.png


LiteFlow 支持所有的關(guān)系型數(shù)據(jù)庫,另外 zk,etcd,nacos 均可支持,還提供了額外的擴展接口,供你自己擴展成其他的存儲方式。 有想過么,你所有的邏輯和規(guī)則編排語法,都是存在于系統(tǒng)之外的。只要更改其腳本和邏輯,你所有節(jié)點的系統(tǒng)不需要做任何事,實時的進行熱變更。 而這一切,LiteFlow 做到了非常平滑,所謂平滑的意思是,不用擔心在熱變更的時候你的業(yè)務(wù)會受到任何的中斷,也不會因為熱變更造成正在執(zhí)行的鏈路產(chǎn)生任何的異常。 LiteFlow 編排能力有多強大呢,簡單的幾個關(guān)鍵字就可以編排出超乎想象的效果:

3d3eb9a2-667d-11ed-8abf-dac502259ad0.png

3d5fac7a-667d-11ed-8abf-dac502259ad0.png

結(jié)語

在 java 的業(yè)務(wù)熱部署領(lǐng)域,LiteFlow 作為一款規(guī)則引擎,給出了一種新的解決思路。 除以上文中介紹的之外,LiteFlow 框架還擁有眾多的高級特性,從各個方位提升你系統(tǒng)的靈活性。 并且作為開源軟件,LiteFlow 擁有國內(nèi)非常好的社區(qū)氛圍和文化。 最后放出 LiteFlow 的官網(wǎng)和倉庫地址,如果你覺得這款開源框架對你的業(yè)務(wù)有幫助,趕緊來了解一下吧 。

項目官網(wǎng): https://liteflow.yomahub.com gitee

托管倉庫: https://gitee.com/dromara/liteFlow github

托管倉庫: https://github.com/dromara/liteflow

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2943

    瀏覽量

    104101
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4671

    瀏覽量

    67767
  • 虛擬機
    +關(guān)注

    關(guān)注

    1

    文章

    888

    瀏覽量

    27812

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

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    SpringBoot 如何實現(xiàn)部署

    SpringBoot 如何實現(xiàn)部署? 1、部署的優(yōu)點 開發(fā)周期通常包括編寫代碼、編譯、部署
    的頭像 發(fā)表于 09-30 10:16 ?731次閱讀
    SpringBoot 如何實現(xiàn)<b class='flag-5'>熱</b><b class='flag-5'>部署</b>

    [轉(zhuǎn)帖]JAVA私塾關(guān)于實訓項目的總結(jié)

    :絕對要指導學生親自動手做,而不是看和聽,所以盡量不要選擇現(xiàn)成代碼項目,演示用的項目也最好不配發(fā)代碼,讓學生能夠跟著做出來才是真的掌握了
    發(fā)表于 01-03 12:04

    Java工程師必須掌握的技術(shù)哪些?

    )spirngMvc 等等的其他一些相似的框架,還有項目架構(gòu)中經(jīng)常會用到的緩存框架例如memcached ,ehcache,oscache等Java緩存框架,需要掌握基本使用,部署,性能調(diào)優(yōu),配置4. 數(shù)據(jù)庫基礎(chǔ)數(shù)據(jù)庫
    發(fā)表于 02-09 16:18

    詳解java代碼優(yōu)化方法

    Java代碼優(yōu)化是Java編程開發(fā)很重要的一個步驟,Java代碼優(yōu)化要注重細節(jié)優(yōu)化,一個兩個的細節(jié)的優(yōu)化,產(chǎn)生的效果不大,但是如果處處都能注
    發(fā)表于 04-02 15:43

    用AD8367做音頻AGC不能做到AGC

    上面的解法 CAGC電容也換過 CHP與C4都換過 RB改為電位器也只能改變放大倍數(shù)不能做到AGC求解是還有什么地方需要修改還是哪里問題謝謝
    發(fā)表于 08-22 10:18

    docker中java環(huán)境的部署

    docker 部署java環(huán)境以及常用應(yīng)用(持續(xù)更新)
    發(fā)表于 05-24 15:44

    linux的java項目部署

    b.因為tomcat的安裝依賴于Java jdk,所以我們需要在判斷l(xiāng)inux系統(tǒng)下面是否安裝jdk
    發(fā)表于 07-25 08:41

    是否可能通過引導加載器從sd卡下載可執(zhí)行代碼的閃存程序?

    大家好,我一個項目,包括一個串行tft顯示器+觸摸屏+sd卡,圖18F46K22我的問題是:是否可能通過引導加載器,從sd卡下載可執(zhí)行代碼
    發(fā)表于 09-10 14:16

    是否可能通過配置寄存器關(guān)閉所有的LED?

    只是想知道,是否可能通過配置寄存器關(guān)閉所有的LED?我問的原因是…Led非常適合于設(shè)置和運行,但是在一些應(yīng)用中,每天運行很少閃爍的LED會非常煩人。如果通過軟件他們可以關(guān)閉,這將是美妙的…我試圖找出如果其中一種模式可以
    發(fā)表于 10-22 11:59

    如何避免在每次部署部署到RAM時閃爍代碼?

    每次部署都需要很長時間的編程和驗證。我們想加快部署過程。到目前為止,我們所有的 IDE 都允許將圖像部署到 RAM。MCUxpresso
    發(fā)表于 03-27 06:51

    Java遠程部署插件的使用方法

    ,長則幾十分鐘都有可能,漫長的打包流程浪費了我們大量的青春,市面上有很多 java 部署的插件,要么是只能修改方法體而不能新增字段和方法,要么就是只能在本地熱
    的頭像 發(fā)表于 09-07 10:43 ?572次閱讀
    <b class='flag-5'>Java</b>遠程<b class='flag-5'>熱</b><b class='flag-5'>部署</b>插件的使用方法

    jrebel和idea部署優(yōu)勢

    開發(fā)效率: JRebel 和 IntelliJ IDEA 的部署可以快速將代碼變更應(yīng)用于運行中的應(yīng)用程序,節(jié)省了反復重啟服務(wù)器的時間。開發(fā)人員可以即時看到代碼變更的結(jié)果,無需等待應(yīng)用
    的頭像 發(fā)表于 12-03 15:16 ?620次閱讀

    eclipse怎么運行java項目

    代碼添加到項目中。您可以通過右鍵單擊項目名稱,然后選擇“New” > “Class”來創(chuàng)建一個新的Java類。在彈出的對話框中,輸入類的名稱和
    的頭像 發(fā)表于 12-06 11:25 ?1699次閱讀

    idea怎么創(chuàng)建Java項目

    (Integrated Development Environment)是開發(fā)Java項目的必備工具。常見的Java IDEEclipse、IntelliJ IDEA和NetBea
    的頭像 發(fā)表于 12-06 14:09 ?745次閱讀

    java反編譯的代碼可以修改么

    Java反編譯是一種將編譯后的Java字節(jié)碼(.class文件)轉(zhuǎn)換回源代碼的過程。反編譯后的代碼可以進行修改,但是需要注意,反編譯代碼的質(zhì)
    的頭像 發(fā)表于 09-02 11:00 ?170次閱讀