作者| 阿里文娛技術(shù)專家 嘉若
責(zé)編 | 屠敏
封圖 | CSDN 下載自東方 IC
背景
作為開發(fā)者,在面對需求變更期間,我們通常的狀態(tài)是開發(fā)-自測-聯(lián)調(diào),需要頻繁改動代碼,即使修改少量代碼,也要重啟容器來檢查執(zhí)行效果。等待時間少則3-5分鐘,多則10分鐘以上,嚴(yán)重加長了非開發(fā)時間。
有沒有更好的方式來解決這一問題?一種方案是寫出沒bug的代碼,這顯然很難,因為很多bug并非是技術(shù)型的,更多的是業(yè)務(wù)型;另一方案就是采用動態(tài)語言,比如node.js,erlang,但這也就意味著技術(shù)選型的單一,以及放棄其他語言的生態(tài)。
那么,作為以JAVA語言為主的開發(fā)者,尋找一種可動態(tài)部署的方案,就是非常靠譜的是可行方案。
Java動態(tài)加載
ClassLoader
說到動態(tài)部署,jvm的類加載機(jī)制是一個繞不過去的問題。我們都知道jvm采用雙親委派模式,Java 類是通過 Java 虛擬機(jī)加載的,某個類的 class 文件在被 classloader 加載后,會生成對應(yīng)的 Class 對象,之后就可以創(chuàng)建該類的實例。
基于雙親委派的模式既能保證jvm的安全性,也能基于此更高效的執(zhí)行class轉(zhuǎn)換的字節(jié)碼指令,加快執(zhí)行速度。
默認(rèn)的虛擬機(jī)行為只會在啟動時加載類,類被加載后就不會被替換和更新,如果要實現(xiàn)動態(tài)加載,需要改變classLoader的加載行為,令jvm監(jiān)聽到class文件的更新,重新加載class文件,但同時如此也會對jvm的安全留下大坑,如此需要十分謹(jǐn)慎。
HotSwap
在jdk1.4期間,jvm就引入了hotswap,允許調(diào)試者使用同一個類標(biāo)識來更新類的字節(jié)碼,避免了類的字節(jié)碼被修改就重載容器。但這個弊端是僅限于修改方法體的修改——也就是說除了方法體,不能添加方法域,也不能修改其他任何代碼。
目前商業(yè)軟件JRebel也做到在極少限制的情況,做到動態(tài)更新類的變動,但是這種方案商業(yè)應(yīng)用收費,兼容性方面有待考驗。
阿里開發(fā)的hotCode,也可以做到熱部署,采用的是遵守hotswap規(guī)則,同時采用代理的方式支持類字節(jié)碼的改變,目前已經(jīng)支持到不限于方法體的改動,可以增加以及修改方法,解決了類級別的頻繁修改部署問題,但針對應(yīng)用級別(變化數(shù)量多)的還是需要重啟容器來解決。

多ClassLoader
基于應(yīng)用級別的動態(tài)加載,我們可以理解為整個應(yīng)用的類改動比較大 ,采用雙親委派模式,我們就需要重新啟動整個應(yīng)用來解決了。
但Tomcat給我們了不同的解決方案,tomcat也是支持動態(tài)部署的,tomcat把classLoader重新設(shè)計了,也是沿用雙親委派的模式之上,新擴(kuò)展了自己的classLoader,借此來管理和分離不同App的加載。
tomcat啟動的時候會有啟動一個線程檢查加載的類是否發(fā)生變化(具體參考Lifecycle的實現(xiàn)),如果發(fā)生了變化就會把應(yīng)用的啟動的線程停止掉清理,同時把該應(yīng)用的WebAPPClassLoader廢棄,再創(chuàng)建一個新的WebAPPClassLoader加載APP。
多classLoader的優(yōu)點:
1)同一進(jìn)程可以加載不同的APP,即便有相同的className;
2)不同APP可以共享類庫,容器提前加載,無需多次加載;
3)APP 類隔離,減少沖突,同時單個APP的重加載不影響其他APP(但無法內(nèi)存和cpu隔離)。
微應(yīng)用平臺的Class動態(tài)加載
YMAP(優(yōu)酷微應(yīng)用平臺),借鑒serverLess思想,支持應(yīng)用秒級部署,快速擴(kuò)縮容,支撐業(yè)務(wù)快速靈活變更,讓開發(fā)者只專注于業(yè)務(wù)。在熱部署方面,我們對比了多種方案。
方案對比
|
方案 |
優(yōu)點 |
缺點 |
|
熱部署 |
快速 |
局部更新 |
|
多classsLoader |
基于classLoader業(yè)務(wù)隔離 |
實現(xiàn)成本高 |
因為YMAP要做一個平臺化的方案,所以不能只限于熱部署,還要考慮到應(yīng)用方的二方庫擴(kuò)展以及多文件的變動,要做到快速,簡單,易用,所以我們最終采用了多classLoader的方案。
class卸載
多classLoader的只是更好的解決了類隔離的問題,但要實現(xiàn)動態(tài)部署的還需要結(jié)合jvm的class卸載的能力,那么怎樣才能卸載class?
JVM中的Class只有滿足以下三個條件,才能被GC回收,也就是該Class被卸載(unload):
1) 該類所有的實例都已經(jīng)被GC。
2) 加載該類的ClassLoader實例已經(jīng)被GC。
3) 該類的java.lang.Class對象沒有在任何地方被引用。
如此,基于YMAP(優(yōu)酷微應(yīng)用平臺)ClassLoader的隔離,有新的應(yīng)用代碼部署的時候,采用新老classLoader的替換的方式,回收老APP的資源,就能做到不啟動容器的情況下,做到應(yīng)用的重新部署。
YMAP(優(yōu)酷微應(yīng)用平臺) ClassLoader
以上就是YMAP的classLoader的架構(gòu)全貌,我們在多classLoader基礎(chǔ)之上,增加一些更貼合業(yè)務(wù)的落地方案。
1) 原生支持spring的全能力,方便開發(fā);
2) 中間件(DB,cache)以及基礎(chǔ)能力無需重復(fù)接入,一站支持,讓業(yè)務(wù)方只關(guān)心業(yè)務(wù)代碼;
3) 支持二方包自定義擴(kuò)展,增加業(yè)務(wù)開發(fā)靈活性;
4) 支持資源隔離(CPU和內(nèi)存隔離),支持混合部署,提升機(jī)器利用率;
5) 快速動態(tài)部署,20s以內(nèi)。
資源隔離
Tomcat的多APP部署一直沒有沒有被推廣的原因之一,就是安全性太低了,多個APP之間會因為資源劃分的問題被相互影響,那么如何解決資源隔離問題?
我們引入了集團(tuán)AliJdk的多租戶能力,復(fù)用的是linux的cgroup的能力,這個方案可以讓單臺機(jī)器上的部署的多個APP之間資源(內(nèi)存、CPU)相互隔離。
常見的資源隔離問題主要表現(xiàn)在多個應(yīng)用對資源的爭奪,比如APP1出現(xiàn)了死循環(huán),導(dǎo)致耗費了整個機(jī)器資源的cpu,其他應(yīng)用無法繼續(xù)獲得指令集的執(zhí)行時間。以及常見的內(nèi)存泄漏,也會導(dǎo)致其他應(yīng)用出現(xiàn)不可訪問的情況。
另外我們做過一個調(diào)查,發(fā)現(xiàn)多數(shù)的長尾應(yīng)用在90%的時間,機(jī)器資源都是浪費的,如果給這類的應(yīng)用采用硬件分離部署,會過多的浪費主機(jī)資源,不如采用多租戶的方式,單容器部署多個應(yīng)用,可以大幅提升資源利用率。
ymap引入了多租戶能力,通過JVM的虛擬化/資源隔離,以支持容器的多租戶,讓多個應(yīng)用可以同時部署在同一個容器而互相不受影響,從而可以更大程度的提高資源利用率,降低單應(yīng)用的部署成本。
多租戶能力的引入,解決了以下痛點:
1) 資源隔離能力,包括IO資源和CPU資源隔離,以及mem隔離;
2) 高密度部署,降低應(yīng)用部署成本;
3) 減少進(jìn)程間溝通(序列化開銷),打通共享能力。
快速部署
YmapClassLoader 幫助我們解決了技術(shù)上動態(tài)加載能力,同時我們也配套了相應(yīng)的APP打包編譯系統(tǒng),結(jié)合aone的構(gòu)建和git代碼管理能力,方便開發(fā)者快速變更和部署,從開發(fā)提交代碼,到編譯部署,再到測試反饋,提供一站式服務(wù),整個過程控制在30s以內(nèi),方便開發(fā)者快速驗證,無需耗費過多的時間再部署發(fā)布上。

優(yōu)酷微應(yīng)用平臺的生態(tài)
YMAP(優(yōu)酷微應(yīng)用平臺)的設(shè)計初心是希望實現(xiàn)類serverless的微服務(wù)平臺,讓開發(fā)者只關(guān)心專注于業(yè)務(wù)邏輯:
在設(shè)計上,基于低成本、安全、高效為關(guān)鍵目標(biāo),為研發(fā)賦能;
在開發(fā)上,支持一站式發(fā)布體系,從開發(fā),測試到發(fā)布,全部可視化支持;
在容器上,動態(tài)部署能力,多租戶隔離能力,以及基礎(chǔ)服務(wù)擴(kuò)展能力,提升應(yīng)用部署效率,以及資源利用率;
在運維上,幫應(yīng)用實現(xiàn)智能化運維工作,應(yīng)用自動接入監(jiān)控報警,一鍵快速擴(kuò)縮容,應(yīng)用運維大盤以及微服務(wù)日志自動云端化可視化等,提升應(yīng)用的運維效率。
微應(yīng)用平臺服務(wù)架構(gòu)
微應(yīng)用平臺業(yè)務(wù)效果
YMAP(優(yōu)酷微應(yīng)用平臺)基于serverless的思想,讓應(yīng)用服務(wù)化,提供最小邏輯單元,讓業(yè)務(wù)快速開發(fā)落地,同時也兼顧資源效率的提升,采用1:N的部署方式,進(jìn)可能的提升主機(jī)利用率。從開發(fā)賦能到運維賦能,為業(yè)務(wù)方帶來更低的成本,更靈活的應(yīng)對方式。






