高德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來開發的。

在阿里集團,淘系前端團隊開發了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-1、清明、雙旦、春節的出行高峯,不再需要運維或者業務開發同學在節前提前擴容,節後再縮容了。

高德業務高峯的特點還不同於電商的秒殺場景。出行高峯的流量不是在一秒內突然漲起來的,我們目前利用池化技術實現的秒級彈性的能力,完全能滿足高德的這個業務場景需求。

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

5. 後續計劃

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

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

歡迎對Serverless、雲原生、或者Go應用開發感興趣的小夥伴,想一起做點事情的同學來加入我們(不管之前是什麼技術棧,英雄不問出處,投簡歷到 [email protected],郵件主題爲:姓名-技術方向-來自高德技術),這裏有大規模的落地場景和簡單開放的技術氛圍。歡迎自薦或推薦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章