高德為什麼要搞 Serverless/Faas?是如何做 Serverless/Faas 的?技術方案是什麼樣的?目前進展怎麼樣?後續又有哪些計劃?本文将和大家做一個簡單的分享。
作者 | 鄧學祥(祥翼)
來源 | Serverless 公衆号
高德從 FY21 财年開始啟動 Serverless 建設,至今一年了,高德 Serverless 業務的峰值超過十萬 qps 量級,平台從 0 到 1,qps 從零到十萬,成為阿裡集團内 Serverless 應用落地規模最大的 BU,這中間的過程是怎麼樣的?遇到過哪些問題?高德為什麼要搞 Serverless/Faas?是如何做 Serverless/Faas 的?技術方案是什麼樣的?目前進展怎麼樣?後續又有哪些計劃?本文将和大家做一個簡單的分享。
1. Why-高德為什麼要搞 Serverless
高德為什麼要搞 Serverless?背景原因是高德 FY21 财年啟動了一個用戶端上雲項目。用戶端上雲項目的主要目的是為了提升用戶端的開發疊代效率。
以前用戶端業務邏輯都在端上,産品需求的變更需要走用戶端發版才能釋出,而用戶端發版需要走各種測試流程、灰階流程,解決用戶端崩潰等問題,目前的節奏是一個月一個版本。
用戶端上雲之後,某些易變的業務邏輯放到雲上來。新的産品需求在雲端來開發,不用走月度的版本釋出,加快了需求的開發疊代效率,離産研同頻的理想目标又近了一步(為什麼要說“又”,是因為高德之前也做了一些優化往産研同頻的方向努力,但是我們希望雲端一體化開發可以是其中最有效的一個技術助力)。

1.1 目标:用戶端開發模式--端雲一體
雖然開發模式從以前的端開發轉變為現在的雲 + 端開發,開發同學應該還是原來負責相應業務的同學,但是大家知道,服務端開發和用戶端開發顯然是有差異的,用戶端開發是面向單機模式的開發,服務端開發通常是叢集模式,需要考慮分布式系統的協調、負載均衡、故障轉移降級等各種複雜問題。如果使用傳統的服務端模式來開發,這個過渡風險就會比較大。
Faas 很好地解決了這一問題。我們結合高德用戶端現有的 xbus 架構(一套用戶端上的本地服務注冊、調用的架構),擴充了 xbus-cloud 元件,使得雲上的開發就像端上開發一樣,目标是一套代碼、兩地運作,一套業務代碼既能在用戶端上運作,也能在服務端上運作。
高德用戶端主要有三個端:IOS、android、車機(類 Linux 作業系統)。主要有兩種語言:C++ 和 Node.js。傳統地圖功能:如地圖顯示、導航路徑顯示、導航播報等等,由于需要跨三個端,采用的 C++ 語言來開發。地圖導航基礎之上的一些地圖應用功能,如行前/行後卡片、推薦目的地等,主要用 Node.js 來開發。
FY20 财年淘系前端團隊開發了 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 定義除了對系統的可維護性有好處以外,對後續支撐業務的疊代開發也很重要,好的 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 是雲時代的進階語言
FY21,高德是集團内第一個全面上雲的 BU,雖然高德已經全面上雲了,但是這還不是雲時代的終局,目前主要是全面 pouch 化并上雲,容器方面做了标準化,在規模化、資源使用率方面可以全面享受雲的紅利,但是業務開發模式上基本上還和以前一樣,仍是一個大型的分布式系統的寫法。對于研發模式來說還并沒有享受雲的紅利,可以類比為我們現在是在用彙編語言的方式來寫跑在雲上的服務。而 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. How-技術方案介紹:在集團現有基礎設施之上做加法
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. How-業務如何接入 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. Now-我們目前的情況
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 的自動彈性擴縮容技術,高德應對各種出行高峰就更從容了。例如每年的十一出行節、五一、清明、春節的出行高峰,不再需要運維或者業務開發同學在節前提前擴容,節後再縮容了。高德業務高峰的特點還不同于電商的秒殺場景。出行高峰的流量不是在 1 秒内突然漲起來的,我們目前利用池化技術實作的秒級彈性的能力,完全能滿足高德的這個業務場景需求。
第三個收益是:降低成本。高德的業務特點,白天流量大、夜間流量低,高峰值和低谷值差異較大,時間段區分明顯。利用 Serverless 在夜間流量低峰時自動縮容技術,極大地降低了伺服器資源的成本。
5. Next-後續計劃
- FC 彈内函數計算使用優化,和 FC 團隊一起持續優化彈内函數計算的性能、穩定性、使用體驗。用集團内豐富的大流量業務場景,來不斷打磨好 C++/Go Faas Runtime,并最終輸出到公有雲,普惠數字化轉型浪潮中的更多企業。
- Dapr 落地,解決 outcoming 流量去中心化問題,逐漸上線一些 C++/Go Faas,使用 Dapr 的方式調用集團中間件。
- Faas 混沌工程,故障演練,逃生能力建設。Faas 在新财年也會參與我們 BU 的故障演練,逐一解決演練過程中發現的問題。
- 接入邊緣計算。端雲一體的場景下,Faas + 邊緣計算,能提供更低的延時,更好的使用者體驗。
以上要做的事情任重道遠,另外 FY22 财年我們部門還會做雲原生的試點和落地。技術同學都知道,從技術選型、技術原型到實際業務落地,這之間還有很長的路要走。
歡迎對 Serverless、雲原生、或者 Go 應用開發感興趣,想一起做點事情的小夥伴來加入我們(不管之前是什麼技術棧,英雄不問出處,投履歷到 [email protected],郵件主題為:姓名-技術方向-來自 Serverless),這裡有大規模的落地場景和簡單開放的技術氛圍,歡迎自薦或推薦!
本文整理自阿裡巴巴進階技術專家--祥翼在【阿裡雲 Serverless Developer Meetup 上海站】上的分享
ppt 擷取方式:關注 Serverless 公衆号,背景對話框回複“ppt”即可
直播回放觀看位址:https://developer.aliyun.com/live/246653