Serverless 如何做到快速發布?微應用平台技術實踐

csdn 發佈 2020-08-14T15:11:23+00:00

我們都知道jvm採用雙親委派模式,Java 類是通過 Java 虛擬機加載的,某個類的 class 文件在被 classloader 加載後,會生成對應的 Class 對象,之後就可以創建該類的實例。

作者| 阿里文娛技術專家 嘉若

責編 | 屠敏

封圖 | CSDN 下載自東方 IC

背景

作為開發者,在面對需求變更期間,我們通常的狀態是開發-自測-聯調,需要頻繁改動代碼,即使修改少量代碼,也要重啟容器來檢查執行效果。等待時間少則3-5分鐘,多則10分鐘以上,嚴重加長了非開發時間。

有沒有更好的方式來解決這一問題?一種方案是寫出沒bug的代碼,這顯然很難,因為很多bug並非是技術型的,更多的是業務型;另一方案就是採用動態語言,比如node.js,erlang,但這也就意味著技術選型的單一,以及放棄其他語言的生態。

那麼,作為以Java語言為主的開發者,尋找一種可動態部署的方案,就是非常靠譜的是可行方案。

Java動態加載

ClassLoader

說到動態部署,jvm的類加載機制是一個繞不過去的問題。我們都知道jvm採用雙親委派模式,Java 類是通過 Java 虛擬機加載的,某個類的 class 文件在被 classloader 加載後,會生成對應的 Class 對象,之後就可以創建該類的實例。

基於雙親委派的模式既能保證jvm的安全性,也能基於此更高效的執行class轉換的字節碼指令,加快執行速度。

默認的虛擬機行為只會在啟動時加載類,類被加載後就不會被替換和更新,如果要實現動態加載,需要改變classLoader的加載行為,令jvm監聽到class文件的更新,重新加載class文件,但同時如此也會對jvm的安全留下大坑,如此需要十分謹慎。

HotSwap

在jdk1.4期間,jvm就引入了hotswap,允許調試者使用同一個類標識來更新類的字節碼,避免了類的字節碼被修改就重載容器。但這個弊端是僅限於修改方法體的修改——也就是說除了方法體,不能添加方法域,也不能修改其他任何代碼。

目前商業軟體JRebel也做到在極少限制的情況,做到動態更新類的變動,但是這種方案商業應用收費,兼容性方面有待考驗。

阿里開發的hotCode,也可以做到熱部署,採用的是遵守hotswap規則,同時採用代理的方式支持類字節碼的改變,目前已經支持到不限於方法體的改動,可以增加以及修改方法,解決了類級別的頻繁修改部署問題,但針對應用級別(變化數量多)的還是需要重啟容器來解決。

多ClassLoader

基於應用級別的動態加載,我們可以理解為整個應用的類改動比較大 ,採用雙親委派模式,我們就需要重新啟動整個應用來解決了。

tomcat給我們了不同的解決方案,tomcat也是支持動態部署的,tomcat把classLoader重新設計了,也是沿用雙親委派的模式之上,新擴展了自己的classLoader,藉此來管理和分離不同APP的加載。

tomcat啟動的時候會有啟動一個線程檢查加載的類是否發生變化(具體參考Lifecycle的實現),如果發生了變化就會把應用的啟動的線程停止掉清理,同時把該應用的WebAPPClassLoader廢棄,再創建一個新的WebAPPClassLoader加載APP。

多classLoader的優點:

1)同一進程可以加載不同的APP,即便有相同的className;

2)不同APP可以共享類庫,容器提前加載,無需多次加載;

3)APP 類隔離,減少衝突,同時單個APP的重加載不影響其他APP(但無法內存和cpu隔離)。

微應用平台的Class動態加載

YMAP(優酷微應用平台),借鑑serverLess思想,支持應用秒級部署,快速擴縮容,支撐業務快速靈活變更,讓開發者只專注於業務。在熱部署方面,我們對比了多種方案。

方案對比

方案

優點

缺點

熱部署

快速

局部更新

多classsLoader

基於classLoader業務隔離

實現成本高

因為YMAP要做一個平台化的方案,所以不能只限於熱部署,還要考慮到應用方的二方庫擴展以及多文件的變動,要做到快速,簡單,易用,所以我們最終採用了多classLoader的方案。

class卸載

多classLoader的只是更好的解決了類隔離的問題,但要實現動態部署的還需要結合jvm的class卸載的能力,那麼怎樣才能卸載class?

JVM中的Class只有滿足以下三個條件,才能被GC回收,也就是該Class被卸載(unload):

1) 該類所有的實例都已經被GC。

2) 加載該類的ClassLoader實例已經被GC。

3) 該類的java.lang.Class對象沒有在任何地方被引用。

如此,基於YMAP(優酷微應用平台)ClassLoader的隔離,有新的應用代碼部署的時候,採用新老classLoader的替換的方式,回收老APP的資源,就能做到不啟動容器的情況下,做到應用的重新部署。

YMAP(優酷微應用平台) ClassLoader

以上就是YMAP的classLoader的架構全貌,我們在多classLoader基礎之上,增加一些更貼合業務的落地方案。

1) 原生支持spring的全能力,方便開發;

2) 中間件(DB,cache)以及基礎能力無需重複接入,一站支持,讓業務方只關心業務代碼;

3) 支持二方包自定義擴展,增加業務開發靈活性;

4) 支持資源隔離(CPU和內存隔離),支持混合部署,提升機器利用率;

5) 快速動態部署,20s以內。

資源隔離

Tomcat的多APP部署一直沒有沒有被推廣的原因之一,就是安全性太低了,多個APP之間會因為資源劃分的問題被相互影響,那麼如何解決資源隔離問題?

我們引入了集團AliJdk的多租戶能力,復用的是linux的cgroup的能力,這個方案可以讓單台機器上的部署的多個APP之間資源(內存、CPU)相互隔離。

常見的資源隔離問題主要表現在多個應用對資源的爭奪,比如APP1出現了死循環,導致耗費了整個機器資源的cpu,其他應用無法繼續獲得指令集的執行時間。以及常見的內存泄漏,也會導致其他應用出現不可訪問的情況。

另外我們做過一個調查,發現多數的長尾應用在90%的時間,機器資源都是浪費的,如果給這類的應用採用硬體分離部署,會過多的浪費主機資源,不如採用多租戶的方式,單容器部署多個應用,可以大幅提升資源利用率。

ymap引入了多租戶能力,通過JVM的虛擬化/資源隔離,以支持容器的多租戶,讓多個應用可以同時部署在同一個容器而互相不受影響,從而可以更大程度的提高資源利用率,降低單應用的部署成本。

多租戶能力的引入,解決了以下痛點:

1) 資源隔離能力,包括IO資源和CPU資源隔離,以及mem隔離;

2) 高密度部署,降低應用部署成本;

3) 減少進程間溝通(序列化開銷),打通共享能力。

快速部署

YmapClassLoader 幫助我們解決了技術上動態加載能力,同時我們也配套了相應的APP打包編譯系統,結合aone的構建和git代碼管理能力,方便開發者快速變更和部署,從開發提交代碼,到編譯部署,再到測試反饋,提供一站式服務,整個過程控制在30s以內,方便開發者快速驗證,無需耗費過多的時間再部署發布上。

優酷微應用平台的生態

YMAP(優酷微應用平台)的設計初心是希望實現類serverless的微服務平台,讓開發者只關心專注於業務邏輯:

在設計上,基於低成本、安全、高效為關鍵目標,為研發賦能;

在開發上,支持一站式發布體系,從開發,測試到發布,全部可視化支持;

在容器上,動態部署能力,多租戶隔離能力,以及基礎服務擴展能力,提升應用部署效率,以及資源利用率;

在運維上,幫應用實現智能化運維工作,應用自動接入監控報警,一鍵快速擴縮容,應用運維大盤以及微服務日誌自動雲端化可視化等,提升應用的運維效率。

微應用平台服務架構

微應用平台業務效果

YMAP(優酷微應用平台)基於serverless的思想,讓應用服務化,提供最小邏輯單元,讓業務快速開發落地,同時也兼顧資源效率的提升,採用1:N的部署方式,進可能的提升主機利用率。從開發賦能到運維賦能,為業務方帶來更低的成本,更靈活的應對方式。

關鍵字: