主頁 > 軟體設計 > 美團Serverless平臺Nest的探索與實踐

美團Serverless平臺Nest的探索與實踐

2021-04-24 12:30:51 軟體設計

Serverless是目前比較熱門的技識訓題,各大云平臺以及互聯網大廠內部都在積極建設Serverless產品,本文將介紹美團Serverless產品在落地程序中的一些實踐經驗,其中包括技術選型的考量、系統的詳細設計、系統穩定性優化、產品的周邊生態建設以及在美團的落地情況,雖然各個公司的背景不盡相同,但總有一些可以相互借鑒的思路或方法,希望能給大家帶來一些啟發或者幫助,

  • 1 背景

  • 2 快速驗證,落地MVP版本

    • 2.1 技術選型

    • 2.2 架構設計

    • 2.3 流程設計

    • 2.4 函式觸發

    • 2.5 函式執行

    • 2.6 彈性伸縮

  • 3 優化核心技術,保障業務穩定性

    • 3.1 彈性伸縮優化

    • 3.2 冷啟動優化

    • 3.3 高可用保障

    • 3.4 容器穩定性優化

  • 4 完善生態,落實收益

    • 4.1 提供研發工具

    • 4.2 融合技術生態

    • 4.3 開放平臺能力

    • 4.4 支持合并部署

  • 5 落地場景、收益

    • 5.1 落地場景

    • 5.2 落地收益

  • 6 未來規劃

  • 作者簡介

  • 招聘資訊

1 背景

Serverless一詞于2012年被提出,2014年由于亞馬遜的AWS Lambda無服務器計算服務的興起,而被大家廣泛認知,Serverless通常被直譯成“無服務器”,無服務器計算是可以讓用戶在不考慮服務器的情況下構建并運行應用程式,使用無服務器計算,應用程式仍在服務器上運行,但所有服務器管理作業均由Serverless平臺負責,如機器申請、代碼發布、機器宕機、實體擴縮容、機房容災等都由平臺幫助自動完成,業務開發只需考慮業務邏輯的實作即可,

回顧計算行業的發展歷程,基礎設施從物理機到虛擬機,再從虛擬機到容器;服務架構從傳統單體應用架構到SOA架構,再從SOA架構到微服務架構,從基礎設施和服務架構兩條主線來看整體技術發展趨勢,大家可能會發現,不論是基礎設施還是服務架構,都是從大往小或者由巨到微的方向上演進,這種演變的本質原則無非是解決資源成本或者研發效率的問題,當然,Serverless也不例外,它也是用來解決這兩個方面的問題:

  • 資源利用率:Serverless產品支持快速彈性伸縮能力,能夠幫助業務提升資源利用率,在業務流量高峰時,業務的計算能力、容量自動擴容,承載更多的用戶請求,而在業務流量下降時,所使用的資源也會同時收縮,避免資源浪費,

  • 研發運維效率:在Serverless上開發人員一般只需要填寫代碼路徑或者上傳代碼包,平臺能夠幫助完成構建、部署的作業,開發人員不直接面對機器,對于機器的管理,機器是否正常以及流量高低峰的是否需要擴縮容等問題,這些統統不需要去考慮,由Serverless產品幫助研發人員去完成,這樣就能使他們從繁瑣的運維作業中解放出來,從DevOps轉向NoOps,更加專注于業務邏輯的實作,

雖然AWS在2014年就推出了第一個Serverless產品Lambda,但Serverless技術在國內的應用一直不溫不火,不過近兩三年,在容器、Kubernetes以及云原生等技術的推動下,Serverless技術迅速發展,國內各大互聯網公司都在積極建設Serverless相關產品,探索Serverless技術的落地,在這種背景下,美團也于2019年初開始了Serverless平臺的建設,內部專案名稱為Nest

截止到目前,Nest平臺已經過兩年的建設,回顧整體的建設程序,主要經歷了以下三個階段:

  • 快速驗證,落地MVP版本:我們通過技術選型、產品與架構設計、開發迭代,快速落地了Serverless產品的基本的能力,如構建、發布、彈性伸縮、對接觸發源、執行函式等,上線后,我們推進了一些業務的試點接入,幫助驗證打磨產品,

  • 優化核心技術,保障業務穩定性:有了前期的試點業務驗證,我們很快發現產品的存在的一些穩定性相關的問題,主要有彈性伸縮的穩定性、冷啟動的速度、系統與業務的可用性、容器的穩定性,針對這些問題我們對各個問題涉及的技術點做了專項的優化改進,

  • 完善技術生態,落實收益:優化了核心技術點后,產品逐漸成熟穩定,但依然面臨生態性問題,如研發工具欠缺,上下游產品沒有打通、平臺開放能力不足等問題,影響或阻礙了產品的推廣使用,因此,我們繼續完善產品的技術生態,掃清業務接入使用障礙,落實產品的業務收益,

2 快速驗證,落地MVP版本

2.1 技術選型

建設Nest平臺,首要解決的就是技術選型問題,Nest主要涉及三個關鍵點的選型:演進路線、基礎設施、開發語言,

2.1.1 演進路線

起初Serverless服務主要包含FaaS(Function as a Service)和BaaS(Backend as a Service),近幾年Serverless的產品領域有所擴張,它還包含面向應用的Serverless服務,

  • FaaS:是運行在一個無狀態的計算容器中的函式服務,函式通常是事件驅動、生命周期很短(甚至只有一次呼叫)、完全由第三方管理的,業界相關FaaS產品有AWS的Lambda、阿里云的函式計算等,

  • BaaS:是建立在云服務生態之上的后端服務,業界相關BaaS產品包括AWS的S3、DynamoDB等,

面向應用的Serverless服務:如Knative,它提供了從代碼包到鏡像的構建、部署以及實體彈性伸縮等全面的服務托管能力,公有云產品有Google Cloud Run(基于Knative)、阿里云的SAE(Serverless Application Engine),

在美團內部,BaaS產品其實就是內部的中間件以及底層服務等,它們經過多年的發展,已經非常豐富且成熟了,因此,在美團的Serverless產品演進主要在函式計算服務和面向應用的Serverless服務兩個方向上,那究竟該如何演進呢?當時主要考慮到在業界FaaS函式計算服務相對于面向應用的Serverless服務來說,更加成熟且確定,因此,我們決定“先建設FaaS函式計算服務,再建設面向應用的Serverless服務”這樣一條演進路線,

2.1.2 基礎設施

由于彈性伸縮是Serverless平臺必備的能力,因此Serverless必然涉及到底層資源的調度和管理,這也是為什么當前業界有很多開源的Serverless產品(如OpenFaaS、Fission、Nuclio、Knative等)是基于Kubernetes來實作的,因為這種選型能夠充分利用Kubernetes的基礎設施的管理能力,在美團內部基礎設施產品是Hulk,雖然Hulk是基于Kubernetes封裝后的產品,但Hulk在落地之初考慮到落地難度以及各種原因,最終未按照原生的方式來使用Kubernetes,并且在容器層采用的也是富容器模式,

在這種歷史背景下,我們在做基礎設施選型時就面臨兩種選項:一是使用公司的Hulk來作為Nest的基礎設施(非原生Kubernetes),二是采用原生Kubernetes基礎設施,我們考慮到當前業界使用原生Kubernetes是主流趨勢并且使用原生Kubernetes還能充分利用Kubernetes原生能力,可以減少重復開發,因此,最終考量的結果是我們采用了原生Kubernetes作為我們的基礎設施

2.1.3 開發語言

雖然無論在云原生領域,還是Kubernetes的生態中,Golang都更加主流,但在美團Java才是使用最廣泛的語言,相比Golang,Java在公司內部生態比較好,因此,在語言的選型上我們選擇了Java語言,在Nest產品開發之初,Kubernetes社區的Java客戶端還不夠完善,但隨著專案的推進,社區的Java客戶端也逐漸豐富了起來,目前已經完全夠用了,另外,我們也在使用程序中,也貢獻了一些Pull Request,反哺了社區,

2.2 架構設計

基于以上的演進路線、基礎設施、開發語言的選型,我們進行了Nest產品的架構設計,

在整體的架構上,流量由EventTrigger(事件觸發源,如Nginx、應用網關、定時任務、訊息佇列、RPC呼叫等)觸發到Nest平臺,Nest平臺內會根據流量的特征路由到具體函式實體,觸發函式執行,而函式內部代碼邏輯可以呼叫公司內的各個BaaS服務,最終完成函式的執行,回傳結果,

圖1 FaaS架構圖

在技術實作上,Nest平臺使用Kubernetes作為基礎底座并適當參考了一些Knative的優秀設計,在其架構內部主要由以下幾個核心部分組成:

  • 事件網關:核心能力是負責對接外部事件源的流量,然后路由到函式實體上;另外,網關還負責統計各個函式的進出流量資訊,為彈性伸縮模塊提供伸縮決策的資料支撐,

  • 彈性伸縮:核心能力是負責函式實體的彈性伸縮,伸縮主要根據函式運行的流量資料以及實體閾值配置計算函式目標實體個數,然后借助Kubernetes的資源控制能力,調整函式實體的個數,

  • 控制器:核心能力是負責Kubernetes CRD(Custom Resource Definition)的控制邏輯實作,

  • 函式實體:函式的運行實體,當事件網關流量觸發過來,會在函式實體內執行相應的函式代碼邏輯,

  • 治理平臺:面向用戶使用的平臺,負責函式的構建、版本、發布以及一些函式元資訊的管理等,

圖2 Nest架構圖

2.3 流程設計

在具體的CI/CD流程上,Nest又與傳統的模式有何區別呢?為了說明這個問題,我們先來看一看在Nest平臺上函式的整體生命周期怎樣的?具體有以下四個階段:構建、版本、部署、伸縮,

  • 構建:開發的代碼和配置通過構建生成鏡像或可執行檔案,

  • 版本:構建生成的鏡像或可執行檔案加上發布配置形成一個不可變的版本,

  • 部署:將版本發布,即完成部署,

  • 伸縮:根據函式實體的流量以及負載等資訊,來進行實體的彈性擴縮容,

就這四個階段來看,Nest與傳統的CI/CD流程本質區別在于部署和伸縮:傳統的部署是感知機器的,一般是將代碼包發布到確定的機器上,但Serverless是要向用戶屏蔽機器的(在部署時,可能函式的實體數還是0);另外,傳統的模式一般是不具備動態擴縮容的,而Serverless則不同,Serverless平臺會根據業務的自身流量需要,進行動態擴縮容,后續章節會詳細講解彈性伸縮,因此這里我們只探討部署的設計,

部署的核心點在于如何向用戶屏蔽機器?對于這個問題,我們抽象了機器,提出了分組的概念,分組是由SET(單元化架構的標識,機器上會帶有該標識)、泳道(測驗環境隔離標識,機器上會帶有該標識)、區域(上海、北京等)三個資訊組成,用戶部署只需在相應的分組上進行操作,而不用涉及到具體機器,能夠做到這些的背后,是由Nest平臺幫助用戶管理了機器資源,每次部署會根據分組資訊來實時初始化相應的機器實體,

圖3 函式生命周期

2.4 函式觸發

函式的執行是由事件觸發的,完成函式的觸發,需要實作以下四個流程:

  • 流量引入:向事件源注冊事件網關的資訊,將流量引入到事件網關,如針對MQ事件源,通過注冊MQ的消費組,引入MQ的流量到事件網關,

  • 流量適配:事件網關對事件源進入的流量進行適配對接,

  • 函式發現:對函式元資料(函式實體資訊、配置資訊等)的獲取程序,類似微服務的服務發現程序,事件網關接受的事件流量需要發送到具體的函式實體,這就需要對函式進行發現,這里發現實質是獲取Kubernetes中的內置資源或者CRD資源中存盤的資訊,

  • 函式路由:事件流量的路由程序,路由到特定的函式實體上,這里為了支持傳統路由邏輯(如SET、泳道、區域路由等)以及版本路由能力,我們采用了多層路由,第一層路由到分組(SET、泳道、區域路由),第二層路由到具體版本,同版本內的實體,通過負載均衡器選擇出具體實體,另外,通過該版本路由,我們很輕松的支持了金絲雀、藍綠發布,

圖4 函式觸發

2.5 函式執行

函式不同于傳統的服務,傳統的服務是個可執行的程式,但函式不同,函式是代碼片段,自身是不能單獨執行的,那流量觸發到函式實體后,函式是如何執行的呢?

函式的執行的首要問題是函式的運行環境:由于Nest平臺是基于Kubernetes實作的,因此函式一定是運行在Kubernetes的Pod(實體)內,Pod內部是容器,容器的內部是運行時,運行時是函式流量接收的入口,最終也是由運行時來觸發函式的執行,一切看起來是那么的順利成章,但我們在落地時是還是遇到了一些困難,最主要的困難是讓開發同學可以在函式內無縫的使用公司內的組件,如OCTO(服務框架)、Celler(快取系統)、DB等,

在美團的技術體系中,由于多年的技術沉淀,很難在一個純粹的容器(沒有任何其他依賴)中運行公司的業務邏輯,因為公司的容器中沉淀了很多環境或服務治理等能力,如服務治理的Agent服務以及實體環境配置、網路配置等,

因此,為了業務在函式內無縫的使用公司內的組件,我們復用公司的容器體系來降低業務撰寫函式的成本,但復用公司的容器體系也沒那么簡單,因為在公司內沒有人試過這條路,Nest是公司第一個基于原生Kubernetes建設的平臺,“第一個吃螃蟹的人”總會遇到一些坑,對于這些坑,我們只能在推程序序中“逢山開路,遇水搭橋”,遇到一個解決一個,總結下來,其中最核心的是在容器的啟動環節打通的CMDB等技術體系,讓運行函式的容器與開發同學平時申請的機器用起來沒有任何區別,

圖5 函式執行

2.6 彈性伸縮

彈性伸縮的核心問題主要有三個:什么時候伸縮,伸縮多少,伸縮的速度快不快?也就是伸縮時機、伸縮演算法、伸縮速度的問題,

  • 伸縮時機:根據流量Metrics實時計算函式期望實體數,進?擴縮,流量的Metrics資料來自于事件網關,這里主要統計函式的并發度指標,彈性伸縮組件每秒中會主動從事件網關獲取一次Metrics資料,

  • 伸縮演算法:并發度/單實體閾值=期望實體數,根據收集的Metrics資料以及業務配置的閾值,通過演算法計算出期望的實體數,然后通過Kubernetes介面設定具體實體數,整個演算法看起來雖然簡單,但非常穩定、魯棒性好,

  • 伸縮速度:主要取決于冷啟動時間,在下個章節會詳細講解這塊內容,

除了基本的擴縮容能力,我們還支持了伸縮到0,支持配置最大、最小實體數(最小實體即預留實體),伸縮到0的具體實作是,我們在事件網關內部增加了激活器模塊,當函式無實體時,會將函式的請求流量快取在激活器內部,然后立即通過流量的Metrics去驅動彈性伸縮組件進行擴容,等擴容的實體啟動完成后,激活器再將快取的請求重試到擴容的實體上觸發函式執行,

圖6 彈性伸縮

3 優化核心技術,保障業務穩定性

3.1 彈性伸縮優化

上面提到的伸縮時機、伸縮演算法、伸縮速度這三要素都是理想情況下的模型,尤其是伸縮速度,當前技術根本做不到毫秒級別的擴縮容,因此,在線上實際場景中,彈性伸碩訓存在一些不符合預期的情況,比如實體伸縮比較頻繁或者擴容來不及,導致服務不太穩定的問題,

  • 針對實體伸縮比較頻繁問題,我們在彈性伸縮組件內維護了統計資料的滑動窗?,通過計算均值來平滑指標,還通過延時縮容,實時擴容來緩解頻繁擴縮問題,另外,我們增加了基于QPS指標的伸縮策略,因為QPS指標相對并發度指標會更加穩定,

  • 針對擴容來不及問題,我們采取提前擴容的手段,當達到實體閾值的70%就擴容,能夠比較好的緩解這個問題,除此之外,我們還支持了多指標混合伸縮(并發度、QPS、CPU、Memory),定時伸縮等策略,滿足各種業務需求,

下圖展示的是線上彈性伸縮的真實案例(配置的最小實體數為4,單實體閾值100,閾值使用率0.7),其中上半部分是業務每秒的請求數,下半部分是擴縮實體的決策圖,可以看到在成功率100%的情況下,業務完美應對流量高峰,

圖7 彈性伸縮案例

3.2 冷啟動優化

冷啟動是指在函式呼叫鏈路中包含了資源調度、鏡像/代碼下載、啟動容器、運行時初始化、用戶代碼初始化等環節,當冷啟動完成后,函式實體就緒,后續請求就能直接被函式執行,冷啟動在Serverless領域至關重要,它的耗時決定了彈性伸縮的速度,

所謂“天下武功,無堅不破,唯快不破”,這句話在Serverless領域也同樣受用,試想如果拉起一個實體足夠快,快到毫秒級別,那幾乎所有的函式實體都可以縮容到0,等有流量時,再擴容實體處理請求,這對于存在高低峰流量的業務將極大的節省機器資源成本,當然,理想很豐滿,現實很骨感,做到毫秒級別幾乎不可能,但只要冷啟動時間越來越短,成本自然就會越來越低,另外,極短的冷啟動時間對伸縮時函式的可用性以及穩定性都有莫大的好處,

圖8 冷啟動的各個階段

冷啟動優化是個循序漸進的程序,我們對冷啟動優化主要經歷了三個階段:鏡像啟動優化、資源池優化、核心路徑優化,

  • 鏡像啟動優化:我們對鏡像啟動程序中的耗時環節(啟動容器和運行時初始化)進行了針對性優化,主要對容器IO限速、一些特殊Agent啟動耗時、啟動盤與資料盤資料拷貝等關鍵點的優化,最終將啟動程序中的系統耗時從42s優化到12s左右,

圖9 鏡像啟動優化成果
  • 資源池優化:鏡像啟動耗時優化到12s,基本已經快達到瓶頸點,再繼續優化空間不大,因此,我們想能否繞開鏡像啟動的耗時環節?最終,我們采用了一個比較簡單思路“空間換時間”,用資源池方案:快取一些已啟動的實體,當需要擴容時,直接從資源池獲取實體,繞開鏡像啟動容器的環節,最終效果很明顯,將啟動的系統耗時從12s優化到3s,這里需要說明的是資源池自身也是通過Kubernetes的Depolyment進行管理,池中實體被取走會立即自動補充,

圖10 資源池優化成果
  • 核心路徑優化:在資源池優化的基礎上,我們再次精益求精,針對啟動流程中的下載與解壓代碼兩個耗時環節進行優化,程序中我們采用了高性能的壓縮解壓演算法(LZ4與Zstd)以及并行下載和解壓技術,效果非常好,另外,我們還支持了通用邏輯(中間件、依賴包等)下沉,通過預加載的方式,最終將函式端到端的啟動耗時優化到2s,這就意味著擴容一個函式實體只需要2s(包含函式啟動),如果排除掉函式自身的初始化啟動耗時,平臺側的耗時已在毫秒級別,

3.3 高可用保障

說到高可用,對于一般的平臺,指的就是平臺自身的高可用,但Nest平臺有所不同,Nest的高可用還包含托管在Nest平臺上的函式,因此,Nest的高可用保障需要從平臺和業務函式兩個方面著手,

3.3.1 平臺高可用

對平臺的高可用,Nest主要從架構層、服務層、監控運營層、業務視角層面都做了全面的保障,

  • 架構層:我們針對有狀態服務,如彈性伸縮模塊,采用了主從架構,當主節點例外時從節點會立即替換,另外,我們還實作了架構上的多層隔離,橫向地域隔離:Kubernetes兩地兩集群強隔離、服務(事件網關、彈性伸縮)集群內兩地弱隔離(上海的彈性伸縮只負責上海Kubernetes集群內的業務伸縮,事件網關存在兩地呼叫需求,需訪問兩地Kubernetes),縱向業務線隔離:服務業務線強隔離,不同業務線使用不同集群服務;在Kubernetes層的資源用namespace實作業務線弱隔離,

圖11 部署架構
  • 服務層:主要指的是事件網關服務,由于所有的函式流量都經過事件網關,因此事件網關的可用性尤為重要,這層我們支持了限流和異步化,保障服務的穩定性,

  • 監控運營層:主要通過完善系統監控告警、梳理核心鏈路并推動相關依賴方進行治理,另外,我們會定期梳理SOP并通過故障演練平臺實施故障注入演練,發現系統隱患問題,

  • 業務視角層:我們開發了在線不間斷實時巡檢服務,通過模擬用戶函式的請求流量,實時檢測系統的核心鏈路是否正常,

3.3.2 業務高可用

對于業務高可用,Nest主要從服務層、平臺層兩個層面做了相關的保障,

  • 服務層:支持了業務降級、限流能力:當后端函式故障時,可通過降級配置,回傳降級結果,針對例外的函式流量,平臺支持限制其流量,防止后端函式實體的被例外流量打垮,

  • 平臺層:支持了實體保活、多層級容災以及豐富的監控告警能力:當函式實體例外時,平臺會自動隔離該實體并立即擴容新實體,平臺支持業務多地區部署,在同地區將函式實體盡可能打散不同機房,當宿主機、機房、地區故障時,會立即在可用宿主機、可用機房或可用區重建新實體,另外,平臺自動幫業務提供了函式在時延、成功率、實體伸縮、請求數等多種指標的監控,當在這些指標不符合預期時,自動觸發告警,通知業務開發和管理員,

圖12 業務監控

3.4 容器穩定性優化

前文已提到,Serverless與傳統模式在CI/CD流程上是不同的,傳統模式都是事先準備好機器然后部署程式,而Serverless則是根據流量的高低峰實時彈性擴縮容實體,當新實體擴容出來后,會立即處理業務流量,這聽起來貌似沒什么毛病,但在富容器生態下是存在一些問題的:我們發現剛擴容的機器負載非常高,導致一些業務請求執行失敗,影響業務可用性,

分析后發現主要是因為容器啟動后,運維工具會進行Agent升級、配置修改等操作,這些操作非常耗CPU,同在一個富容器中,自然就搶占了函式行程的資源,導致用戶行程不穩定,另外,函式實體的資源配置一般比傳統服務的機器要小很多,這也加劇了該問題的嚴重性,基于此,我們參考業界,聯合容器設施團隊,落地了輕量級容器,將運維的所有Agent放到Sidecar容器中,而業務的行程單獨放到App容器中,采用這種容器的隔離機制,保障業務的穩定性,同時,我們也推動了容器裁剪計劃,去掉一些不必要的Agent,

圖13 輕量級容器

4 完善生態,落實收益

Serverless是個系統工程,在技術上涉及到Kubernetes、容器、作業系統、JVM、運行時等各種技術,在平臺能力上涉及到CI/CD各個流程的方方面面,

為了給用戶提供極致的開發體驗,我們為用戶提供了開發工具的支持,如CLI(Command Line Interface)、WebIDE等,為了解決現有上下游技術產品的互動的問題,我們與公司現有的技術生態做了融合打通,方便開發同學使用,為了方便下游的集成平臺對接,我們開放了平臺的API,實作Nest賦能各下游平臺,針對容器過重,系統開銷大,導致低頻業務函式自身資源利用率不高的問題,我們支持了函式合并部署,成倍提升資源利用率,

4.1 提供研發工具

開發工具能夠降低平臺的使用成本,幫助開發同學快速的進行CI/CD流程,目前Nest提供了CLI工具,幫助開發同學快速完成創建應用、本地構建、本地測驗、Debug、遠程發布等操作,Nest還提供了WebIDE,支持在線一站式完成代碼的修改、構建、發布、測驗,

4.2 融合技術生態

僅支持這些研發工具還是不夠的,專案推廣使用后,我們很快就發現開發同學對平臺有了新的需求,如無法在Pipeline流水線、線下服務實體編排平臺上完成對函式的操作,這對我們專案的推廣也形成了一些阻礙,因此,我們融合這些公司的成熟技術生態,打通了Pipeline流水線等平臺,融入到現有的上下游技術體系內,解決用戶的后顧之憂,

4.3 開放平臺能力

有很多Nest的下游解決方案平臺,如SSR(Server Side Render)、服務編排平臺等,通過對接Nest的OpenAPI,實作了生產力的進一步解放,例如,不用讓開發同學自己去申請、管理和運維機器資源,就能夠讓用戶非常快速的實作一個SSR專案或者編排程式從0到1的創建、發布與托管,

Nest除了開放了平臺的API,還對用戶提供了自定義資源池的能力,擁有了該項能力,開發同學可以定制自己的資源池,定制自己的機器環境,甚至可以下沉一些通用的邏輯,實作冷啟動的進一步優化,

4.4 支持合并部署

合并部署指的是將多個函式部署在一個機器實體內,合并部署的背景主要有兩個:

  • 當前的容器較重,容器自身的系統開銷較大,導致業務行程資源利用率不高(尤其是低頻業務),

  • 在冷啟動耗時不能滿足業務對時延的要求的情況下,我們通過預留實體來解決業務的需求,

基于這兩個背景,我們考慮支持合并部署,將一些低頻的函式部署到同一個機器實體內,來提升預留實體中業務行程的資源利用率,

在具體實作上,我們參考Kubernetes的設計方案,設計了一套基于Sandbox的函式合并部署體系(每個Sandbox就是一個函式資源),將Pod類比成Kubernetes的Node資源,Sandbox類比成Kubernetes的Pod資源,Nest Sidecar類比成Kubelet,為了實作Sandbox特有的部署、調度等能力,我們還自定義了一些Kubernetes資源(如SandboxDeployment、SandboxReplicaSet、SandboxEndpoints等)來支持函式動態插拔到具體的Pod實體上,

圖14 合并部署架構

除此之外,在合并部署的形態下,函式之間的隔離性也是不可回避的問題,為了盡可能的解決函式(合并在同一個實體中)之間的互相干擾問題,在Runtime的實作上,我們針對Node.js和Java語言的特點采取了不同的策略:Node.js語言的函式使用不同的行程來實作隔離,而Java語言的函式,我們采用類加載隔離,采用這種策略的主要原因是由于Java行程占用記憶體空間相較于Node.js行程會大很多,

5 落地場景、收益

目前Nest產品在美團前端Node.js領域非常受歡迎,也是落地最廣泛的技術堆疊,當前Nest產品在美團前端已實作了規模化落地,幾乎涵蓋了所有業務線,接入了大量的B/C端的核心流量,

5.1 落地場景

具體的落地前端場景有:BFF(Backend For Frontend)、CSR(Client Side Render)/SSR(Server Side Render)、后臺管理平臺、定時任務、資料處理等,

  • BFF場景:BFF層主要為前端頁面提供資料,采用Serverless模式,前端同學不需要考慮不擅長的運維環節,輕松實作了BFF向SFF(Serverless For Frontend)模式的轉變,

  • CSR/SSR場景:CSR/SSR指的是客戶端渲染和服務端渲染,有了Serverless平臺,不用考慮運維環節,更多的前端業務來嘗試使用SSR來實作前端首屏的快速展現,

  • 后臺管理平臺場景:公司有很多的后臺管理平臺的Web服務,它們雖然相較于函式是比較重的,但完全可以直接托管Serverless平臺,充分享受Serverless平臺極致的發布和運維效率,

  • 定時任務場景:公司存在很多周期性任務,如每隔幾秒拉取資料,每天0點清理日志,每小時收集全量資料并生成報表等,Serverless平臺直接與任務調度系統打通,只需寫好任務的處理邏輯并在平臺上配置定時觸發器,即完成定時任務的接入,完全不用管理機器資源,

  • 資料處理場景:將MQ Topic作為事件源接入Serverless平臺,平臺會自動訂閱Topic的訊息,當有訊息消費時,觸發函式執行,類似定時任務場景,作為用戶也只需寫好資料處理的邏輯并在平臺上配置好MQ觸發器,即完成MQ消費端的接入,完全不用管理機器資源,

5.2 落地收益

Serverless的收益是非常明顯的,尤其在前端領域,大量的業務接入已是最好的說明,具體收益,從以下兩個方面分別來看:

  • 降成本:通過Serverless的彈性伸縮能力,高頻業務資源利用率能提升到40%~50%;低頻業務函式通過合并部署,也能極大降低函式運行成本,

  • 提效率:整體研發研發效率提升約40%,

    • 從代碼開發來看,提供完備的CLI、WebIDE等研發工具,能夠幫助開發同學生成代碼腳手架,聚焦撰寫業務邏輯,快速完成本地測驗;另外,讓業務服務零成本具備在線查看日志與監控的能力,

    • 從發布來看,通過云原生的模式,業務無需申請機器,發布、回滾都是秒級別的體驗,另外,還能利用平臺天然能力,配合事件網關,實作切流、完成金絲雀測驗等,

    • 從日常運維來看,業務無需關注機器故障、資源不足、機房容災等傳統模式該考慮的問題,另外,當業務行程例外時,Nest能夠自動完成例外實體的隔離,迅速拉起新實體實作替換,降低業務影響,

6 未來規劃

  • 場景化解決方案:接入Serverless的場景眾多,如SSR、后臺管理端、BFF等,不同的場景有不同的專案模板、場景配置,如伸縮配置、觸發器配置等,另外,不同的語言,配置也有所不同,這無形中增加了業務的使用成本,給新業務的接入帶來了阻礙,因此,我們考慮場景化的思路來建設平臺,將平臺的能力與場景強關聯起來,平臺深度沉淀各場景的基本配置和資源,這樣不同的場景,業務只需要簡單的配置就可以將Serverless玩轉起來,

  • 傳統微服務Serverless化:即是路線選型中提到的面向應用的Serverless服務,在美團使用最廣的開發語言是Java,公司內部存在大量的傳統的微服務專案,這些專案如果都遷移到函式模式,顯然是不現實的,試想如果這些傳統的微服務專案不用改造,也能直接享受Serverless的技術紅利,其業務價值不言而喻,因此,傳統微服務的Serverless化是我們未來拓展業務的一個重要方向,在實施路徑上,我們會考慮將服務治理體系(如ServiceMesh)與Serverless做技術融合,服務治理組件為Serverless提供伸縮指標支持并在伸縮程序中實作精準的流量調配,

  • 冷啟動優化:當前雖然函式的冷啟動優化已經取得了較好的成績,尤其是平臺側的系統啟動耗時,提升空間已經非常有限,但業務代碼自身的啟動耗時還是非常突出,尤其是傳統Java微服務,基本是分鐘級別的啟動耗時,因此,后續我們的冷啟動優化會重點關注業務自身的啟動耗時,爭取極大降低業務自身的啟動時間,在具體優化方法上,我們會考慮采用AppCDS、GraalVM等技術,降低業務自身啟動耗時,

  • 其他規劃

    • 豐富完善研發工具,提升研發效率,如IDE插件等,

    • 打通上下游技術生態,深度融入公司現有技術體系,減少因上下游平臺帶來使用障礙,

    • 容器輕量化,輕量化的容器能夠帶來更優的啟動耗時以及更佳的資源利用率,因此,容器輕量化一直是Serverless的不懈追求,在具體落地上,準備聯合容器設施團隊一起推進容器中的一些Agent采用DaemonSet方式部署,下沉到宿主機,提升容器的有效載荷,

作者簡介

  • 殷琦、華珅、飛飛、志洋、奕錕等,來自基礎架構部應用中間件團隊,

  • 佳文、凱鑫,亞輝等,來自金融技術平臺大前端團隊,

閱讀更多

---

前端 | 演算法 | 后端 | 資料

安全 | Android | iOS | 運維 | 測驗

---------- END ----------

招聘資訊

美團基礎架構團隊誠招高級、資深技術專家,Base北京、上海,我們致力于建設美團全公司統一的高并發高性能分布式基礎架構平臺,涵蓋資料庫、分布式監控、服務治理、高性能通信、訊息中間件、基礎存盤、容器化、集群調度等基礎架構主要的技術領域,歡迎有興趣的同學投送簡歷到:tech@meituan.com,

也許你還想看

| 美團OCTO萬億級資料中心計算引擎技術決議

| 美團集群調度系統HULK技術演進

| Kubernetes如何改變美團的云基礎設施?

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/279573.html

標籤:其他

上一篇:性能測驗知多少 | 什么是性能測驗?性能測驗原理是什么?指標都有哪些?如何進行測驗?

下一篇:搞不懂為啥那么多程式員都想去位元組跳動。。。直到朋友拿到位元組offer,酸了

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more