云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的系統(tǒng)與方法
【技術(shù)領(lǐng)域】
[0001] 本發(fā)明涉及計(jì)算機(jī)系統(tǒng)技術(shù)領(lǐng)域,尤其涉及企業(yè)應(yīng)用系統(tǒng)技術(shù)領(lǐng)域,具體是指一 種云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的系統(tǒng)與方法。
【背景技術(shù)】
[0002] 隨著信息技術(shù)的發(fā)展,許多線下的業(yè)務(wù)模式正在通過互聯(lián)網(wǎng)在線上實(shí)現(xiàn)虛擬化, 通過線下和線上的融合可以最大限度的確保用戶體驗(yàn)。比如某數(shù)碼品牌門店,線下的實(shí)體 門店可以成為用戶的體驗(yàn)場所和倉儲(chǔ)中心,而線上系統(tǒng)則可以成為傳統(tǒng)實(shí)體店突破空間和 時(shí)間限制的24小時(shí)不打烊賣場。線上系統(tǒng)想要提供類似7 X 24小時(shí)的用戶體驗(yàn),這就對IT 系統(tǒng)建設(shè)提出了更高的要求。
[0003] 在基于Java的應(yīng)用系統(tǒng)中,如果需要對生產(chǎn)系統(tǒng)升級(jí)或者打補(bǔ)丁,一般保守的做 法是先停止服務(wù),再升級(jí)系統(tǒng),最后重啟服務(wù),在整個(gè)升級(jí)期間,系統(tǒng)是不可用的。為解決這 一問題,出現(xiàn)了一種灰度發(fā)布的方式,即一次只升級(jí)一部分系統(tǒng),這樣可以始終保證有一部 分系統(tǒng)是可用的,之后再逐步擴(kuò)大升級(jí)范圍,直至全部升級(jí)完成。采用灰度發(fā)布能在一定程 度上解決因系統(tǒng)升級(jí)帶來的服務(wù)不可用的問題,但是,這仍然沒有徹底解決需要停止服務(wù) 的問題。
[0004] 假設(shè)有這樣一個(gè)系統(tǒng),因?yàn)榘l(fā)現(xiàn)了一個(gè)bug或者調(diào)整業(yè)務(wù)規(guī)則需要修改其中一個(gè) Class類,僅僅就為了更新一個(gè)類,就需要對系統(tǒng)進(jìn)行一次升級(jí)。如果沒有Class的熱更新 機(jī)制,這樣的代價(jià)是很大的。
【發(fā)明內(nèi)容】
[0005] 本發(fā)明的目的是克服了上述現(xiàn)有技術(shù)的缺點(diǎn),提供了一種能夠?qū)崿F(xiàn),使生產(chǎn)環(huán)境 中的系統(tǒng)不停機(jī)成為可能、應(yīng)用范圍廣泛的云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的系統(tǒng) 與方法。
[0006] 為了實(shí)現(xiàn)上述目的,本發(fā)明的云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的系統(tǒng)與方 法具有如下構(gòu)成:
[0007] 該云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的系統(tǒng),其主要特點(diǎn)是,所述的系統(tǒng)包 括:
[0008] 自定義加載模塊,用以加載需要熱更新類的自定義類加載器;
[0009] 類掃描模塊,用以對目標(biāo)目錄進(jìn)行類文件掃描并通知熱更新模塊;
[0010] 熱更新模塊,用以對需要進(jìn)行熱更新的類進(jìn)行熱更新;
[0011] 受管對象創(chuàng)建工廠模塊,用以創(chuàng)建作為受管對象的熱更新的類的具體實(shí)例。
[0012] 本發(fā)明還涉及一種云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的方法,其特征在于,所 述的方法包括以下步驟:
[0013] (1)系統(tǒng)啟動(dòng)時(shí),所述的類掃描模塊掃描目標(biāo)目錄的類文件;
[0014] (2)系統(tǒng)將掃描結(jié)果注冊至模型注冊器;
[0015] (3)使用受管對象實(shí)例的模塊向所述的受管對象創(chuàng)建工廠模塊發(fā)出使用請求;
[0016] (4)所述的自定義類加載模塊加載需要熱更新類的自定義類加載器;
[0017] (5)所述的受管對象創(chuàng)建工廠模塊通過所述的自定義類加載器創(chuàng)建受管對象的具 體實(shí)例;
[0018] (6)系統(tǒng)運(yùn)行期間,當(dāng)熱更新事件被觸發(fā),所述的熱更新模塊執(zhí)行熱更新。
[0019] 較佳地,所述的掃描目標(biāo)目錄的類文件,包括如下步驟:
[0020] (1-1)遞歸遍歷特定目錄下的所有后綴為.class的文件并確定需要熱更新的類;
[0021] (1-2)在模型注冊器中保存物理類文件的信息。
[0022] 較佳地,所述的自定義類加載模塊加載需要熱更新類的自定義類加載器,包括以 下步驟:
[0023] (4-1)所述的自定義類加載模塊進(jìn)行初始化;
[0024] (4-2)所述的自定義類加載模塊重寫父類的類尋找方法并加載類模型。
[0025] 更佳地,所述的自定義類加載模塊重寫父類的類尋找方法并加載類模型,包括以 下步驟:
[0026] (4-2-1)根據(jù)類尋找方法傳入類名并使用父加載器加載以及判斷是否加載成功, 如果是,則繼續(xù)步驟(4-2-3),如果否,則繼續(xù)步驟(4-2-2);
[0027] (4-2-2)讀取該物理文件至byte數(shù)組中,調(diào)用父類的defineClass方法由JVM完 成加載,然后繼續(xù)步驟(4-2-3);
[0028] (4-2-3)所述的受管對象創(chuàng)建工廠將加載成功的類模型向模型注冊器注冊。
[0029] 較佳地,所述的創(chuàng)建受管對象的具體實(shí)例,包括以下步驟:
[0030] (5-1)所述的受管對象創(chuàng)建工廠模塊判斷所述的模型注冊器的緩存中是否存在類 模型,如果是,則繼續(xù)步驟(5-2),否則繼續(xù)步驟(5-3);
[0031] (5-2)所述的受管對象創(chuàng)建工廠模塊從所述的模型注冊器的緩存中獲取類模型, 然后繼續(xù)步驟(5-4);
[0032] (5-3)所述的自定義類加載模塊創(chuàng)建自定義加載器并用新創(chuàng)建的自定義加載器加 載該類模型,然后繼續(xù)步驟(5-4);
[0033] (5-4)所述的受管對象創(chuàng)建工廠模塊根據(jù)所述的類模型創(chuàng)建受管對象的具體實(shí) 例;
[0034] (5-5)受管對象創(chuàng)建工廠模塊將受管對象、具體實(shí)例及自定義類加載器注冊至模 型注冊器;
[0035] (5-6)返回受管對象的具體實(shí)例。
[0036] 較佳地,所述的熱更新模塊執(zhí)行熱更新,包括以下步驟:
[0037] (6-1)所述的熱更新模塊從觸發(fā)事件中獲取需要熱更新的類相關(guān)信息;
[0038] (6-2)所述的熱更新模塊根據(jù)類唯一名稱從模型注冊器中移除該類所關(guān)聯(lián)的受管 對象、具體實(shí)例及自定義類加載器;
[0039] (6-3)所述的熱更新模塊通知使用受管對象實(shí)例的模塊類文件發(fā)生變更需重新加 載。
[0040] 更佳地,所述的通知使用受管對象實(shí)例的模塊類文件發(fā)生變更需重新加載,包括 以下步驟:
[0041] (6-3-1)使用受管對象實(shí)例的模塊統(tǒng)一熱更新通知接口并將實(shí)現(xiàn)類注冊至所述的 熱更新服務(wù)模塊;
[0042] (6-3-2)依次調(diào)用實(shí)現(xiàn)了熱更新通知接口的實(shí)現(xiàn)類的通知方法將此次更新的類名 包裝為事件對象傳入;
[0043] (6-3-3)在實(shí)現(xiàn)類中,移除舊的受管對象的實(shí)例的引用;
[0044] (6-3-4)重新向所述的受管對象創(chuàng)建工廠模塊提出對象使用申請;
[0045] (6-3-5)由受管對象創(chuàng)建工廠模塊完成新類的初始及加載工作,并重新在模型注 冊器中注冊。
[0046] 采用了該發(fā)明中的云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的系統(tǒng)與方法,使生產(chǎn) 環(huán)境中的系統(tǒng)不停機(jī)成為可能,當(dāng)生產(chǎn)系統(tǒng)需要打補(bǔ)丁或升級(jí)時(shí),只需要提供要更新的類 文件即可,無需停機(jī)重啟,即時(shí)更新,即時(shí)生效,極大的提高了運(yùn)維效率,降低了運(yùn)維成本, 避免了停機(jī)事故;同時(shí)還增強(qiáng)了系統(tǒng)可移植性和可擴(kuò)展性;不僅如此,該方法還能夠快速 響應(yīng)業(yè)務(wù)需求的變化和技術(shù)變化,能夠支撐建立高度模塊化而且又高度整合的軟件系統(tǒng), 適用范圍較為廣泛,為企業(yè)應(yīng)用軟件技術(shù)的進(jìn)一步發(fā)展打下了堅(jiān)實(shí)的基礎(chǔ)。
【附圖說明】
[0047] 圖1為本發(fā)明的云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的方法的對象依賴關(guān)系圖。
[0048] 圖2為本發(fā)明的云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的方法的熱更新過程流程 圖。
【具體實(shí)施方式】
[0049] 為了能夠更清楚地描述本發(fā)明的技術(shù)內(nèi)容,下面結(jié)合具體實(shí)施例來進(jìn)行進(jìn)一步的 描述。
[0050] 本發(fā)明提出一種云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的方法。在技術(shù)實(shí)現(xiàn)上,要 做到Class熱替換,必須要解決兩個(gè)問題:
[0051] -是舊的Class要被正確回收,如果不回收,多次替換或者有大量Class替換,勢 必有OOM的風(fēng)險(xiǎn),增加系統(tǒng)隱患;對于JVM來說,類的回收是比較苛刻的,需要同時(shí)滿足下面 3個(gè)條件:
[0052] A、該類所有的實(shí)例都已經(jīng)被GC,也就是JVM中不存在該Class的任何實(shí)例。
[0053] B、加載該類的ClassLoader已經(jīng)被GC。
[0054] C、該類對應(yīng)的java. lang. Class對象沒有在任何地方被引用,如不能在任何地方 通過反射訪問該類的方法。
[0055] 保證舊的類被回收,是實(shí)現(xiàn)熱替換的前提條件。
[0056] 二是新的Class要被正確加載,眾所周知,在JVM中,同名的Class在同一個(gè) ClassLoader中不允許被重復(fù)加載,如何突破這一限制,這也是實(shí)現(xiàn)熱替換的關(guān)鍵所在。
[0057] 本發(fā)明針對上述兩個(gè)問題提出解決方案,既保證了舊的Class被回收,又保證新 的Class被正確加載,實(shí)現(xiàn)了真正意義上的熱替換。
[0058] 此發(fā)明的關(guān)鍵設(shè)計(jì)點(diǎn)即在于如圖1所示的模型設(shè)計(jì)。采用一對一的加載模型設(shè) 計(jì),能夠達(dá)到JVM對類回收的三個(gè)條件,從而有效保證舊的Class能被正確回收,使運(yùn)行期 動(dòng)態(tài)熱更新Class成為可能。該一對一的加載模型與OSGi中bundle的類加載機(jī)制異曲同 工,在OSGi中,一個(gè)bundle會(huì)對應(yīng)一個(gè)ClassLoader,本發(fā)明的實(shí)現(xiàn)是一個(gè)業(yè)務(wù)類對應(yīng)一個(gè) ClassLoader,只有這樣,才保證了業(yè)務(wù)類能夠像bundle -樣做到熱更新。
[0059] 該發(fā)明實(shí)現(xiàn)了云計(jì)算環(huán)境下Java類在線熱更新,其實(shí)現(xiàn)方案包含的主要模塊如 下:
[0060] 1、自定義類加載模塊:用于加載需要熱更新類的自定義ClassLoader。本實(shí)例中 以 java. lang. ClassLoader 為父類實(shí)現(xiàn)。
[0061] 2、類加載器:對目標(biāo)目錄進(jìn)行定時(shí)或手工掃描,并通知熱更新模塊。本實(shí)例以掃描 固定目錄下的類文件為例。
[0062] 3、熱更新模塊:對需要進(jìn)行熱更新的類進(jìn)行熱更新。
[0063] 4、受管對象創(chuàng)建工廠模塊:熱更新的類在系統(tǒng)中是受管對象,該模塊負(fù)責(zé)創(chuàng)建受 管對象的具體實(shí)例。
[0064] 所述的在云計(jì)算環(huán)境下實(shí)現(xiàn)Java類在線熱更新的方法,包括如下步驟(其序列圖 參見圖2):
[0065] (1)系統(tǒng)啟動(dòng)時(shí)通過類加載器,掃描目標(biāo)目錄的類文件;
[0066] (2)掃描完成后,將掃描結(jié)果注冊至模型注冊器;
[0067] (3)系統(tǒng)中受管對象實(shí)例的使用者向受管對象創(chuàng)建工廠模塊發(fā)出使用請求;
[0068] (4)受管對象創(chuàng)建工廠模塊通過自定義類加載模塊加載的Class,并