Serverless時代的微服務開發指南:華為雲提出七大實踐新標準
摘要:本文結合華為雲在Serverless Microservice方面的實踐,總結提煉出七大Serverless Microservice開發 “實踐標準”,為加速全域Serverless產業升級、推動企業應用開發框架從微服務向Serverless演進提供一些思考。
作者資訊——
歷川:華為雲 Serverless 研發專家
丙真:華為雲中間件 Serverless 產品經理
馮嘉:華為雲中間件首席專家
一、背景
分散治理、資料去中心化、基礎設施自動化等優秀設計原則,使得微服務架構在過去幾年中逐漸發展為企業應用架構的首選。然而,隨著應用規模的持續增長和微服務生態的成熟,新的挑戰也在不斷湧現出來。相比於傳統SOA等架構, 微服務架構給予開發者更多設計和開發 “自由度”,同一應用的各微服務模組,可以採用不同的技術棧來實現獨立自治的業務邏輯。但自由也相應增加了開發運維的複雜度,提高了軟體開發者的認知成本;同時,微服務架構在業務資源開銷、交付速度、擴充套件效能和基礎設施彈性等方面,也面臨一系列新的挑戰。
Serverless程式設計正規化的興起,允許開發者聚焦業務邏輯本身,無需再感知底層執行時細節和後端資源的維護伸縮等問題,給微服務應用開發提供了效率更高的選擇。本文結合華為雲函式工作流FunctionGraph、事件網格EventGrid以及雲應用引擎 CAE等在Serverless Microservice方面的實踐,總結提煉出包括基礎設施無感知、全生命週期可觀測、 狀態管理自動化等在內的七大Serverless Microservice開發 “實踐標準”,為加速全域Serverless產業升級、推動企業應用開發框架從微服務向Serverless演進提供一些思考。
二、微服務架構新挑戰

圖1. 微服務應用開發的生命週期示意
如圖1所示,在微服務架構中,應用程式由一組功能自治的小型化服務圍繞業務能力構建,服務之間採用輕量級通訊,可以獨立開發、構建、測試、釋出和監控。微服務的目的是有效拆分應用,實現敏捷開發和部署 [1]。Martin Fowler 和 James Lewis在《Microservices: A Definition of This New Architectural Term》中,列舉了微服務架構的九大特徵,如表1所示 (參見 [2]),這些特徵使得微服務相比於傳統軟體開發架構,具有更加靈活的設計開發模式,服務之間支援獨立部署和擴充套件,有效提升了企業應用的開發、迭代和運維效率。
表1:微服務架構的九大特徵

儘管微服務架構秉承眾多優秀設計原則,隨著應用規模增長、技術生態的成熟和工具鏈的多元化發展,一系列新的挑戰逐漸呈現在企業應用開發者面前。
挑戰一:開發運維的複雜性高
相比於單體(Monolithic)或SOA(Service-Oriented Architecture)等傳統架構下的 “規範標準”,微服務更提倡基於 “實踐標準” 解決分散式問題 [2];因此,對於服務註冊發現、負載均衡、配置和安全、事務處理等,在微服務場景中不再有統一的解決方案。例如,服務間通訊方案就有數十種,包括REST、gRPC、Thrift、Dubbo等,服務發現也包含CoreDNS、Eureka、ZooKeeper、ETCD等多種技術選型; 應用開發人員從這些各有千秋的技術中,選擇最適合自己業務場景的系統性方案,無疑是一件門檻很高的任務; 儘管有Spring Cloud等一站式的全家桶工具集,對應用設計和運維人員來說,一攬子工具集所提供的技術組合複雜多樣,導致問題定位、定界效率低。
除Spring Cloud,Kubernetes也逐漸成為一種主流的微服務解決方案。與Spring Cloud相比,Kubernetes的配置管理和服務註冊功能更加友好,且“邊車代理模式”、服務網格 (e.g., Istio) 等技術的提出,顯著提高了服務治理的效率;但要實現這類解決方案的高效利用,開發者的認知成本和所面對的複雜性並不低;從Spring Cloud 到Kubernetes,複雜性沒有被減弱,更多地是被轉移。微服務架構也需要開發者掌握併發程式設計框架和分散式事務一致性等技術,這些技術本身具備不低的複雜性,以事務一致性為例,常見機制就包括TCC (Try-Confirm-Cancel)、2/3PC (2/3 Phase Commit)、SAGA等模式。
挑戰二:服務擴充套件效率與應用規模難平衡
儘管微服務提倡對應用進行拆分,但微服務的粒度仍然比較大。同一個微服務單元中,不同子功能之間的使用頻率(e.g., QPS、RPS et al.)、變更頻率等往往也不相同,因而對擴充套件性的訴求也不一樣。圖2展示了一個Web應用中“使用者管理”微服務的例子[3],該微服務包含賬號註冊API、登入API和登出API三項子功能,在實際使用中,註冊API和登入API的呼叫頻率通常遠高於登出API,因此對擴充套件性的要求也高於後者;此時雖然可以對微服務進一步進行拆分,但整個應用的服務數量也可能會隨之翻倍,從而加重應用基礎設施的管理負擔。

圖2. 一個Web應用中“使用者管理”微服務的示例
微服務粒度較大的問題也使得單個服務的擴容速度十分受限,在高併發場景下要實現微服務的快速彈性是一件十分困難的事;對於時延敏感型應用,併發請求的擴容訴求通常在秒級以內,甚至毫秒級,但在微服務架構下,服務彈性擴容則通常需要秒級以上甚至分鐘級的時延。
挑戰三:高可用與彈性保障成本高
與服務擴充套件效率和應用規模平衡相關的另一個難題是成本問題。受限於單個服務的彈效能力,微服務架構通常採用“多例項主備”或“多例項多活”的方案,來保障應用的高可用性,實現容錯、容災、負載均衡等目標。但與前文中討論的相似,同一個微服務應用的不同子服務之間,其承載的流量大小、呼叫頻率等的差距也可能很大,因此對資源的橫向、縱向擴縮容訴求也不一致,這種差距往往給企業帶來無畏的成本浪費。圖3展示了一個由6個功能不可或缺的子服務構建而成的微服務應用, 每個服務執行在虛機或容器中,圖中實線表示在給定的一段時間內企業為每個服務所佔據的虛機或容器所支付的資源成本,虛線表示服務在業務執行中所實際消耗的資源成本。

圖3. 一個微服務應用的資源成本示意
在圖3的示例中,微服務F由於被呼叫的頻率很高,其所佔據的資源利用率也較高,而微服務A則相反,其所佔據的資源成本和F相差不大(e.g., 2u2G的容器),但A被呼叫的頻率則相對低很多,資源利用率也相應更低。在實際應用開發運維中,為保障高可用性和資源彈性,圖中實線與虛線之間通常存在較大的差距,這部分成本是企業為應用所佔據但未使用的資源付出的成本,屬於一種成本浪費;同時,由於微服務架構通常不支援(一般也不建議)單個服務 “Scale-to-Zero”,且微服務應用逐漸變得越來越 “重”,上述 “資源佔而不用” 導致的浪費現象也更加嚴重。
三、事件驅動式Serverless函式架構
雲原生基礎設施的發展,有力促進了事件驅動的Serverless架構的廣泛應用。相比於微服務,Serverless提供了一種更加細粒度的應用開發模型,以及更加便捷、輕量的應用運維框架。以FaaS(Function-as-a-Service)為例,應用開發支援以單個函式作為最小部署單元,開發者只需提供函式程式碼(包括原始碼檔案、映象等)和一些配置資訊,即可實現應用的快速釋出和上線;同時,後端資源的維護及其隨流量的自適應伸縮等複雜任務,則全部被下移到Serverless平臺側,顯著降低了開發者的認知成本和開發、運維門檻,如圖4所示;開發者只需為應用函式所實際使用的資源時長進行付費,付費粒度精確到毫秒級;同時,在應用流量負載為零的所有時間區間中,函式例項通過“Scale-to-zero”可以有效消除成本浪費,實現應用開發經濟化。

圖4. Serverless應用開發架構的資源邊界示意
與在微服務場景下相似,事件驅動式(Event-driven)也是Serverless函式架構的核心特徵。Serverless函式一般由函式程式碼包和事件處理程式(event handler)構成,函式通過事件進行觸發,並對接收到的事件進行響應、處理。例如,FunctionGraph支援多種型別的事件觸發器,滿足應用在不同業務場景下的訴求;同時,通過原生整合事件網格服務EventGrid,FunctionGraph為各類雲服務、自定義應用、SaaS應用提供了標準化、中心化的接入方式,事件可以在不同應用和服務之間靈活路由,幫助開發者快速構建鬆耦合、分散式的事件驅動式Serverless應用,如圖5所示。

圖5. EFG:基於EventGrid和FunctionGraph的事件驅動式Serverless應用模型
四、基於函式快速實現Serverless Microservice應用
圖6給出了基於FunctionGraph和APIG(API Gateway)的Serverless Microservice簡易應用模型,整個應用採用雲上託管服務(managed services)構建,每個微服務由函式實現,並通過APIG對外暴露,函式之間採用Workflow進行功能編排。在該模型基礎上,我們用函式快速實現一個Serverless Microservice示例。

圖6. 基於FunctionGraph和APIG的Serverless Microservice模型
以經典的電商應用為例,首先用FunctionGraph建立三個函式,分別實現Product, Basket, Order微服務,其中,Product實現商品清單及詳情瀏覽,Basket負責加購,Order完成下單。交易相關的狀態採用分散式快取服務DCS(Distributed Cache Service)進行儲存,DCS例項通過繫結獨立VPC來實現網路私有和隔離,最後,我們為每個函式分別繫結一個APIG觸發器,對外暴露服務;如圖7(1) - 7(5) 所示。

圖7-(1). 分別建立三個函式,實現微服務功能

圖7-(2). 授權FunctionGraph訪問VPC內服務 (i.e., DCS 例項)

圖7-(3). 開啟函式訪問VPC

圖7-(4). 在函式中獲取對應環境變數

圖7-(5). 最後為每個函式繫結APIG觸發器
我們用APIPost進行簡單測試並返回函式介面檢視監控資訊,如圖8(1) – (3) 所示:

圖8-(1). 用APIPost測試函式微服務

圖8-(2). 檢視日誌監控

圖8-(3). 檢視併發數等監控資訊
最後,我們通過EventGrid進行非同步事件解耦,並採用分散式訊息服務DMS(Distributed Message Service)實現基於Fan Out/Fan In的批處理,如圖9所示:

圖9. 一個基於事件驅動的Serverless 函式架構的電商應用示例
其中,EventGrid建立事件訂閱時,事件源選擇DCS例項,事件目標選擇FunctionGraph函式,如圖10所示:

圖10. 建立EventGrid事件訂閱
五、雲上Serverless Microservice實踐標準探索
在基於事件驅動式Serverless函式架構開發應用的過程中,遵循一定的設計/開發原則或“實踐標準”,有利於開發者構建更加高效、經濟和穩健的企業應用。本文結合華為雲FunctionGraph、EventGrid以及 CAE等雲服務在Serverless領域的最佳實踐,總結並提煉出Serverless microservice應用開發的七類實踐標準,為開發者的架構決策提供參考;如表2所示。
表2. 雲上Serverless Microservice 應用開發的實踐標準探索

基礎設施無感知(Infra-less):基礎設施無感知幫助開發者更快、更高效地構建應用程式,並顯著降低應用運維的成本和複雜性。除伺服器無感知外,基礎設施無感知具有更廣泛的含義。包括開發者對平臺底層作業系統、分散式執行時以及硬體的有限制訪問,開發者無需感知FunctionGraph平臺是如何架構的,其它雲服務與FunctionGraph的整合由華為雲統一管理,只公開少量配置選項給開發者,開發者也無需感知函式在任何時間點被呼叫時例項資源位於哪個可用區(Available Zone, AZ),等等;這種抽象允許開發者專注於應用程式本身的功能開發、資料流設計和業務邏輯優化,從而更聚焦地為應用的終端使用者提供價值。
全生命週期可觀測(Deep Observability):基礎設施無感知在提供便捷性的同時,也在開發者的“心智模型”方面降低了透明性,因此,全生命週期、深度、例項級的可觀測性,對於開發者實現對應用的自主掌控具有關鍵作用。Serverless可觀測性包含鏈路追蹤,日誌,和指標三類,主要服務於異常監控、效能調測、故障定位、問題定界等。例如,FunctionGraph通過內建對接雲日誌服務LTS,為應用函式提供日誌監控能力,包括高階日誌分析能力(e.g., loginsight)等;通過對接應用效能管理服務APM,提供指標豐富的函式例項級監控;同時,支援全鏈路呼叫鏈管理等。開發者無需複雜的配置,即可享受應用函式全生命週期的深度可觀測效能力。
流式編排(Flow Orchestration):編排是Serverless的核心概念之一,狹義的編排主要指工作流編排,如FunctionGraph Workflow,在Serverless microservice 應用開發中,開發者應儘量避免在單個函式中定製化地開發應用的各類分支邏輯及其異常處理程式,應儘可能採用函式工作流編排來實現,工作流編排提供了一種更加便捷的分支路由、錯誤捕獲以及異常處理方法,能夠增強應用邏輯的穩健性並提高全鏈路可觀測性 [4]。廣義的編排還包括服務流編排(Service Flow),應用架構所依賴的三方功能,如閘道器、訊息、快取等,也應儘可能採用雲上託管服務,通過配置驅動、服務流編排的方式進行組裝式構建,從而儘可能減少定製化程式碼的開發和維護,降低應用運維的負擔。FunctionGraph原生支援開發者整合雲上其它服務,表3列出了在Serverless microservice開發中最常用的幾類雲服務。
表3:Serverless microservice應用程式開發中常用的幾類雲服務

事件驅動(Event-driven):事件,表示狀態的變化。採用事件驅動的方式構建應用的優點在於鬆耦合、獨立擴縮容、良好的擴充套件性等。在狀態查詢、資料存取、函式呼叫等場景中,優先採用事件來代替傳統應用開發中常用的輪詢、Webhook等機制,可以有效降低應用的複雜性、提高系統性能、或降低應用成本 [5]。以輪詢為例,由於系統狀態的更新在時間維度上不一定是規律且連續的,使得輪詢類策略往往是低效或非經濟的;Webhook 機制則在被整合的服務之間不一定能夠得到廣泛的支援。同時,輪詢和webhook機制在支援應用按需擴縮容方面也存在較大挑戰。採用事件驅動模式,開發者既可以很方便地構建實時系統,實現資料按需流動並避免過量的批處理任務;也可以通過將事件釋出到DMS等訊息服務,利用彈性緩衝區實現非同步解耦,然後利用EventGrid 對事件進行過濾和路由,從而增強應用在流量激變情形下的可伸縮性。
互動式控制(Interactive Autopilot):互動式控制主要解決如何通過廣義的自動駕駛技術(autopilot)[7] 實現應用迭代和生產的高效能、低成本;對於Serverless函式而言,自動駕駛主要包括函式程式碼包瘦身、原始碼優化、資源規格選擇、併發度調優等問題。以函式資源規格選擇為例,過去主要依賴於開發者的工程經驗和其對自身業務場景的理解進行設定,但經驗性配置往往具有誤差大、靜態性、黑盒化等缺點;因此,FunctionGraph提出線上式資源消耗感知與規格動態推薦等autopilot技術,配合離線式最佳規格調優(power tuning),最大限度幫助使用者實現應用函式FinOps效果,讓開發者能夠真正享受到Economical Serverless的福利 [8];開發者無需感知應用自動駕駛技術的實現細節,但整個過程 “處處可觀察、 實時可干預”。
狀態管理自動化(Automatic State Management):儘管Serverless提倡無狀態優先,但在多數分散式應用中,狀態管理是無法迴避且複雜度很高的任務。隨著資料密集型應用逐漸成為雲上應用的主流,如大規模機器學習、大資料與流處理、實時互動型應用、多人協作類應用等,Serverless程式設計框架對支援有狀態的訴求越來越強烈。FunctionGraph 作為業界首個支援有狀態的Serverless平臺,為開發者提供多種狀態一致性模型和自動化的併發處理機制,開發者通常只需要對函式中的簡單結構體進行操作,即可實現狀態資料的快速存取,整個狀態管理過程由平臺內建提供,無需與外部儲存服務之間進行頻繁互動,顯著減少了涉及大量狀態資料操作的網路訪問次數,具有自動化、高效能、高可用等特點。
伸縮原子輕量化(Lightweight Scaling Unit):伸縮原子,指最小可伸縮的執行單元,如單個函式。 在Serverless microservice 應用開發中,函式應儘可能小型化,功能上保持邏輯內聚,以響應外部事件為主,對應用全域性邏輯弱感知;伸縮原子的輕量化,不僅能夠支援快速的獨立擴縮容以及高併發下的快速彈效能力,也能夠最大限度地保證應用的各個微服務函式能夠“按需擴縮容”,從而在保障應用負載QoS的前提下,實現極致成本。
六、總結和展望
以事件驅動式函式架構為代表的Serverless程式設計模型,正在成為微服務應用開發的新一代標準框架。本文結合華為雲FunctionGraph和EventGrid等在Serverless微服務方面的最佳實踐,總結並提煉出七大Serverless Microservice實踐標準, 為推動全域Serverless產業升級提供一些思考。
更進一步地,華為雲事件網格服務EventGrid將於近期正式轉商用,並聯合FunctionGraph推出事件驅動式函式應用開發模型EFG(EventGrid-FunctionGraph); 同時,基於七大實踐標準並結合豐富的客戶實踐,EFG將推出Serverless Microservice參考架構,為開發者構建事件驅動式Serverless解決方案提供視覺化的架構抽象和優秀的業務建模支援。
參考資料
[1] Introduction to Microservices. https://www.nginx.com/blog/introduction-to-microservices/
[2] 周志明,《鳳凰架構:構築可靠的大型分散式系統》
[3] 劉方明, 李林峰, 王磊, 《華為Serverless核心技術與實踐》.
[4] Understanding event-driven architecture – Part 1
[5] Design principles in event-driven architectures – Part 2
[6] Anti-patterns in event-driven architectures
[7] Rzadca, K., Findeisen, P., Swiderski, J., Zych, P., Broniek, P., Kusmierek, J., ... & Wilkes, J. (2020, April). Autopilot: workload autoscaling at google. In Proceedings of the Fifteenth European Conference on Computer Systems (pp. 1-16).
[8] 歷川, 平山, 馮嘉, Serverless 遇到 FinOps: Economical Serverless,
https://www.infoq.cn/article/ckibtiofxn4whycfjt8b
- 使用卷積神經網路實現圖片去摩爾紋
- 核心不中斷前提下,Gaussdb(DWS)記憶體報錯排查方法
- 簡述幾種常用的排序演算法
- 自動調優工具AOE,讓你的模型在昇騰平臺上高效執行
- GaussDB(DWS)運維:導致SQL執行不下推的改寫方案
- 詳解目標檢測模型的評價指標及程式碼實現
- CosineWarmup理論與程式碼實戰
- 淺談DWS函數出參方式
- 程式碼實戰帶你瞭解深度學習中的混合精度訓練
- python進階:帶你學習實時目標跟蹤
- Ascend CL兩種資料預處理的方式:AIPP和DVPP
- 詳解ResNet 網路,如何讓網路變得更“深”了
- 帶你掌握如何檢視並讀懂昇騰平臺的應用日誌
- InstructPix2Pix: 動動嘴皮子,超越PS
- 何為神經網路卷積層?
- 在昇騰平臺上對TensorFlow網路進行效能調優
- 介紹3種ssh遠端連線的方式
- 分散式資料庫架構路線大揭祕
- DBA必備的Mysql知識點:資料型別和運算子
- 5個高併發導致數倉資源類報錯分析