高德Serverless平臺建設及實踐

導讀前端

高德啓動Serverless建設已經有段時間了,目前高德Serverless業務的峯值早已超過十萬QPS量級,平臺從0到1,QPS從零到超過十萬,成爲阿里集團內Serverless應用落地規模最大的BU。這個過程如何實現,遇到過哪些問題?本文將和你們分享高德爲什麼要搞Serverless/Faas,如何作,技術方案是什麼?目前進展以及後續計劃有哪些,但願對感興趣的同窗有所幫助。算法

1. 高德爲何要搞Serverless後端

背景緣由是高德當年啓動了一個客戶端上雲項目,項目主要目的是爲了提高客戶端的開發迭代效率。之前客戶端業務邏輯都在端上,產品需求的變動須要走客戶端發版才能發佈,而客戶端發版須要走各類測試流程,灰度流程,解客戶端崩潰等問題。瀏覽器

客戶端上雲以後,某些易變的業務邏輯放到雲上來。新的產品需求經過在雲端來開發,不用走月度的版本發佈,加快了需求的開發迭代效率,離產研同頻的理想目標又近了一步(爲何要說「又」,是由於高德以前也作了一些優化往產研同頻的方向努力,可是咱們但願雲端一體化開發能是其中最有效的一個技術助力)。性能優化

1.1 目標:客戶端開發模式——端雲一體服務器

雖然開發模式從之前的端開發轉變爲如今的雲 + 端開發,開發同窗應該仍是原來負責相應業務的同窗,而你們知道,服務端開發和客戶端開發顯然是有差別的,客戶端開發每每是面向單機模式的開發,服務端開發一般是集羣模式,須要考慮分佈式系統的協調、負載均衡,故障轉移降級等各類複雜問題。架構

若是使用傳統的服務端模式來開發,這個過渡風險就會比較大。Faas很好的解決了這一問題。咱們結合高德客戶端現有的xbus框架(一套客戶端上的本地服務註冊、調用的框架),擴展了xbus-cloud組件,使得雲上的開發就像端上開發同樣,目標是一套代碼,兩地運行,一套業務代碼既能在客戶端上運行,也能在服務端上運行。併發

高德客戶端主要有三個端:iOS、Android、車機(類Linux操做系統)。主要有兩種語言,C++和Node.js。傳統地圖功能:如地圖顯示,導航路徑顯示,導航播報等等,因爲須要跨三個端,採用C++語言來開發。地圖導航基礎之上的一些地圖應用功能,如行前、行後卡片,推薦目的地等主要是用Node.js來開發的。app

在阿里集團,淘系前端團隊開發了Node.js Faas Runtime。高德客戶端上雲項目,Node.js的部分就採用了現有的淘系的Node.js Runtime,來接入集團的Faas平臺,完成Node.js這部分的一些業務上雲。2020年十一很好的支撐了高德的十一出行節業務。負載均衡

C++ Faas沒有現有的解決方案,所以咱們決定在集團的基礎設施之上作加法,新建C++ Faas基礎平臺,來助力高德客戶端上雲。

1.1.1 端雲一體的最佳實踐關鍵:客戶端和Faas之間的接口抽象

本來客戶端的邏輯移到Faas服務端上來,或者新的需求一部分在Faas服務端上開發,這裏的成敗關鍵點在於:客戶端和Faas的接口協議定義,也就是Faas的API定義。好的API定義除了對系統的可維護性有好處之外,對後續支撐業務的迭代開發也很重要。

理想狀況下:客戶端作成一個解析Faas返回結果數據的一個瀏覽器。瀏覽器協議一旦定義好,就不會常常變換,你看IE,Chrome就不多更新。

固然咱們的這個瀏覽器會複雜一些,咱們這個瀏覽器是地圖瀏覽器。如何檢驗客戶端和Faas之間的接口定義好很差,能夠看後續的產品需求迭代,若是有些產品需求迭代只須要在Faas上完成,不須要客戶端的任何修改,那麼這個接口抽象就是成功的。

1.2 BFF層開發提效

提到高德,你們首先想到的應該是其工具屬性:高德是一個導航工具,(這個說法如今已經不太準確了,由於高德這幾年在作工具化往平臺化轉型,高德的交易類業務正在興起,高德打車、門票、酒店等業務發展很是迅猛)。針對高德導航來講,相比集團其餘業務,相比電商來講,有大量的只讀場景是高德業務的一大技術特色。

這些只讀場景裏,大量的需求是BFF(Backend For Frontend)類型的只讀場景。爲何這麼說,由於導航的最核心功能,例如routing, traffic, eta等都是相對穩定的,這部分的主要工做在用持續不斷的優化算法,使得高德的導航更準,算出的路徑更優。這些核心功能在接口和功能上都是相對比較穩定的,而前端需求是多變的,例如增長個路徑上的限寬墩提示等。

Faas特別適合作BFF層開發,在Faas上調用後端相對穩定的各個Baas服務,Faas服務來作數據和調用邏輯封裝,快速開發、發佈。在業界,Faas用的最多的場景也正是BFF場景(另一個叫法是SFF場景,service for frontend)。

1.3 Serverless是雲時代的高級語言

雖然高德已經全面上雲了,可是目前還不是雲時代的終局,目前主要是全面Docker化並上雲,容器方面作了標準化,在規模化,資源利用率方面能夠全面享受雲的紅利,可是業務開發模式上基本還和之前同樣,仍是一個大型的分佈式系統的寫法。

對於研發模式來講還並無享受雲的紅利,能夠類比爲咱們如今是在用匯編語言的方式來寫跑在雲上的服務。而Serverless、雲原生能夠理解爲雲時代的高級語言,真正作到了Cloud as a computer,只須要關注於業務開發,不須要考慮大型分佈式系統的各類複雜性。

1.4 Go-Faas補充Go語言生態

前面講到了由於客戶端上雲項目,咱們在阿里雲FC(函數計算)團隊之上作加法,開發了C++ Faas Runtime。

不只如此,咱們還開發了Go-Faas,爲何會作Go-Faas呢,這裏也簡單介紹一下背景,高德服務端Go部分的QPS峯值已超百萬。高德已補齊了阿里各中間件的Go客戶端,和集團中間件部門共建。可觀測性、自動化測試體系也基本完善,目前Go生態已基本完善。補齊了Go-Faas以後,咱們就既能用Go寫Baas服務,又能用Go寫Faas服務了,在不一樣的業務場景採用不一樣的服務實現方式,Go-Faas主要應用於上文提到的BFF場景。

2. 技術方案介紹——在集團現有基礎設施之上作加法

2.1 總體技術架構

上文講了咱們爲何要作這個事情,如今來說一下咱們具體是怎麼作這個事情:如何實現,具體的技術方案是什麼樣的。

咱們本着在集團現有的基礎設施、現有的中間件基礎之上作加法的思想,咱們和CSE,阿里雲FC函數計算團隊合做共建,開發了C++ Faas Runtime 和 Go Faas Runtime。總體和集團拉通的技術架構以下圖所示,主要分爲研發態、運行態、運維態三個部分。

2.1.1 運行態

先說運行態,業務流量從網關進來,調用到FC API Server,轉發到C++/Go Faas Runtime,Runtime來完成用戶函數裏的功能。Runtime的架構下一章節來具體介紹。

和Runtime Container一塊兒部署的有監控、日誌、Dapr各類Side car,Side car來完成各類日誌採集上報功能,Dapr Side car來完成調用集團中間件的功能。

另外,目前Dapr還在試點的階段,調用中間件主要是經過Broker和各個中間件Proxy來完成,中間件調用的有HSF,Tair,Metaq,Diamond等中間件Proxy。

最後Autoscaling模塊來管理函數實例的擴縮容,達到函數自動伸縮的目的。這裏的調度就有各類策略了,有根據請求併發量的調度,函數實例的CPU使用率的調度。也能提早設置預留實例數,避免縮容到0以後的冷啓動問題。

底層調用的是集團ASI的能力,ASI能夠簡單理解爲集團的K8S + Sigma(集團的調度系統),最終的部署是FC調用ASI來完成函數實例部署。彈性伸縮的,部署的最小單位是上圖中的POD,一個POD裏包含Runtime Container和Sidecar Set Container。

2.1.2 研發態

再來看研發態,運行態是決定函數是如何運行的,研發態關注的函數的開發體驗。如何方便的讓開發者開發、調試、部署、測試一個函數。

C++ Faas有個跨平臺的難點問題,C++ Faas Runtime裏有一些依賴庫,這些依賴庫沒有Java依賴庫管理那麼方便。這些依賴庫的安裝比較麻煩,Faas腳手架就是爲了解決這個問題,調用腳手架,一鍵生成C++ Faas示例工程,安裝好各類依賴包。爲了本地能方便的Debug,開發了一個C++ Faas Runtime Boot模塊,函數Runtime啓動入口在Boot模塊裏,Boot模塊裏集成Runtime和用戶Faas函數,能夠對Runtime來作Debug單步調試。

咱們和集團Aone團隊合做,函數的發佈集成到Aone環境上了,能夠很方便的在Aone上來發布Go或者C++ Faas,Aone上也集成了一鍵生成Example代碼庫的功能。

C++和Go Faas的編譯都依賴相應的編譯環境,Aone提供了自定義編譯鏡像的功能,咱們上傳了編譯鏡像到集團的公共鏡像庫,函數編譯時,在函數的代碼庫裏指定相應的編譯鏡像。編譯鏡像裏安裝了Faas的依賴庫,SDK等。

2.1.3 運維態

最後來看函數的運維監控,Runtime內部集成了鷹眼、Sunfire採集日誌的功能,Runtime裏面會寫這些日誌,經過Sidecar裏的Agent採集到鷹眼、或者Sunfire監控平臺上去(FC是經過SLS來採集的)以後,就能使用集團現有的監控平臺來作Faas的監控了。也能接入集團的GOC報警平臺。

2.2 C++/Go Faas Runtime架構

上面講的是和Aone,FC/CSE,ASI集成的一個總體架構,Runtime是這個總體架構的一部分,下面具體講講Runtime的架構是怎樣的,Runtime是如何設計和實現的。

最上面部分的用戶Faas代碼只須要依賴Faas SDK就能夠了,用戶只須要實現Faas SDK裏的Function接口就能寫本身的Faas。

而後,若是須要調用外部系統,能夠經過SDK裏的Http Client來調用,若是要調用外部中間件,經過SDK裏的Diamond/Tair/HSF/Metaq Client來調用中間件就能夠。SDK裏的這些接口屏蔽了底層實現的複雜性,用戶不須要關心這些調用最後是如何實現,不須要關心Runtime的具體實現。

SDK層就是上面提到的Function定義和各類中間件調用的接口定義。SDK代碼是開發給Faas用戶的。SDK作的比較輕薄,主要是接口定義,不包含具體的實現。調用中間件的具體實如今Runtime裏有兩種實現方式。

再來看上圖中間藍色的部分,是Runtime的一個總體架構。Starter是Runtime的啓動模塊,啓動以後,Runtime自身是一個Server,啓動的時候根據Function Config模塊的配置來啓動Runtime,Runtime啓動以後開啓請求和管理監聽模式。

往下是Service層,實現SDK裏定義的中間件調用的接口,包含RSocket和Dapr兩種實現方式,RSocket是經過RSocket broker的模式來調用中間件的,Runtime裏集成了Dapr(distributed application runtime) ,調用中間件也能夠經過Dapr來調用,在前期Dapr試點階段,若是經過Dapr調用中間件失敗了,會降級到RSocket的方式來調用中間件。

再往下就是RSocket的協議層,封裝了調用RSocket的各類Metadata協議。Dapr調用是經過GRPC方式來調用的。最下面一層就是集成了RSocket和Dapr了。

RSocket調用還涉及到Broker選擇的問題,Upstream模塊來管理Broker cluster,Broker的註冊反註冊,Keepalive檢查等等,LoadBalance模塊來實現Broker的負載均衡選擇,以及事件管理,鏈接管理,重連等等。

最後Runtime裏的Metrics模塊負責鷹眼Trace的接入,經過Filter模式來攔截Faas鏈路的耗時,並輸出鷹眼日誌。打印Sunfire日誌,供Sidecar去採集。下圖是一個實際業務的Sunfire監控界面:

2.2.1 Dapr

Dapr架構見下圖所示,具體能夠參考看官方文檔

Runtime裏之前調用中間件是經過RSocket方式來調用的,這裏RSocket Broker會有一箇中心化問題,爲了解決Outgoing流量去中心化問題,高德和集團中間件團隊合做引入了Dapr架構。只是Runtime層面集成了Dapr,對於用戶Faas來講無感知,不須要關心具體調用中間件是經過RSocket調用的仍是經過Dapr調用的。後面Runtime調用中間件切換到Dapr以後,用戶Faas也是不須要作任何修改的。

3. 業務如何接入Serverless

如前文所述,統一在Aone上接入。咱們提供了C++ Faas/Go Faas的接入文檔。提供了函數的Example代碼庫,代碼庫有各類場景的示例,包括調用集團各類中間件的代碼示例。

C++ Faas/Go Faas的接入面向整個集團開放,目前已經有一些高德之外的BU,在本身的業務中落地了C++ /Go Faas了。

Node.js Faas使用淘寶提供的Runtime和模板來接入,Java Faas使用阿里雲FC提供的Runtime和模板來接入就能夠了。

3.1 接入規範——穩定性三板斧:可監控、可灰度、可回滾

針對落地新技術你們可能擔憂的穩定性問題,應對法寶是阿里集團的穩定性三板斧:可監控、可灰度、可回滾。創建Faas鏈路保障羣,拉通上下游各相關業務方、基礎平臺一塊兒,按照集團的1-5-10要求,作到1分鐘以內響應線上報警,快速排查,5分鐘以內處理;10分鐘以內恢復。

爲了規範接入過程,避免犯錯誤引起線上故障,咱們制定了Faas接入規範和CheckList,來幫助業務方快速使用Faas。

可監控、可灰度、可回滾是硬性要求,除此以前,業務方若是能作到可降級就更好了。咱們的C++客戶端上雲業務,在開始試點的階段,就作好了可降級的準備,若是調用Faas端失敗,本次調用將會自動降級到本地調用。基本上對於客戶端功能無損,只是會增長一些響應延遲。

另外,客戶端上該功能的版本,可能會比服務端稍微老一點,可是功能是向前兼容的,基本不影響客戶端使用。

4. 咱們目前的狀況

4.1 基礎平臺建設狀況

  • Go/C++ Faas Runtime開發完成,對接FC-Ginkgo/CSE、Aone完成,已發佈穩定的1.0版本。
  • 作了大量的穩定性建設、優雅下線、性能優化、C編譯器優化,使用了阿里雲基礎軟件部編譯器優化團隊提供的編譯方式來優化C++ Faas的編譯,性能提高明顯。
  • C++/Go Faas接入鷹眼、Sunfire監控完成,函數具有了可觀測性。
  • 池化功能完成,具有秒級彈性的能力。池化Runtime鏡像接入CSE,擴一個新實例的時間由原來的分鐘級變爲秒級。

4.2 高德的Serverless業務落地狀況

C++ Faas和Go Faas以及Node.js Faas在高德內部已經有大量應用落地了。舉幾個例子:

上圖中的前兩個圖是C++ Faas開發的業務:長途天氣、沿途搜。後兩個截圖是Go-Faas開發的業務:導航Tips,足跡地圖。

高德是阿里集團內Serverless應用落地規模最大的BU,已落地的Serverless應用,平常峯值早已超過十萬QPS量級。

4.3 主要收益

高德落地了集團內規模最大的Serverless應用以後,都有哪些收益呢?首先,第一個最重要的收益是:開發提效。咱們基於Serverless實現的端雲一體組件,助力了客戶端上雲,解除了需求實現時的客戶端發版依賴問題,提高了客戶端的開發迭代效率。基於Serverless開發的BFF層,提高了BFF類場景的開發迭代效率。

第二個收益是:運維提效。利用Serverless的自動彈性擴縮容技術,高德應對各類出行高峯就更從容了。例如每一年的10-1出行節,5-一、清明、雙旦、春節的出行高峯,再也不須要運維或者業務開發同窗在節前提早擴容,節後再縮容了。

高德業務高峯的特色還不一樣於電商的秒殺場景。出行高峯的流量不是在一秒內忽然漲起來的,咱們目前利用池化技術實現的秒級彈性的能力,徹底能知足高德的這個業務場景需求。

第三個收益是:下降成本。高德的業務特色,白天流量大、夜間流量低,高峯值和低谷值差別較大,時間段區分明顯。利用Serverless在夜間流量低峯時自動縮容技術,極大的下降了服務器資源的成本。

5. 後續計劃

  • FC彈內函數計算使用優化,和FC團隊一塊兒持續優化彈內函數計算的性能、穩定性、使用體驗。用集團內的豐富的大流量業務場景,不斷打磨好C++/Go Faas Runtime,並最終輸出到公有云,普惠數字化轉型浪潮中的更多企業。
  • Dapr落地,解決Outcoming流量去中心化問題,逐步上線一些C++/Go Faas,使用Dapr的方式調用集團中間件。
  • Faas混沌工程,故障演練,逃生能力建設。Faas在新財年也會參與咱們BU的故障演練,逐一解決演練過程當中發現的問題。
  • 接入邊緣計算。端雲一體的場景下,Faas + 邊緣計算,能提供更低的延時,更好的用戶體驗。

以上要作的事情任重道遠,另外咱們將來還會作更多雲原生的試點和落地,技術同窗都知道,從技術選型、技術原型到實際業務落地,這之間還有很長的路要走。

歡迎對Serverless、雲原生、或者Go應用開發感興趣的小夥伴,想一塊兒作點事情的同窗來加入咱們(無論以前是什麼技術棧,英雄不問出處,投簡歷到 gdtech@alibaba-inc.com,郵件主題爲:姓名-技術方向-來自高德技術),這裏有大規模的落地場景和簡單開放的技術氛圍。歡迎自薦或推薦。

相關文章
相關標籤/搜索