浅析 Dapr 里的云计算设计模式
Dapr 實際上是把分布式系統(tǒng) 與微服務架構實踐的挑戰(zhàn)以及k8s 這三個主題的全方位的設計組合,特別是Kubernetes設計模式?一書作者Bilgin Ibryam?提出的Multi-Runtime Microservices Architecture,中譯參見敖小劍的博客:?[譯] 多運行時微服務架構。
分布式系統(tǒng) 和微服務架構實踐的核心問題就是要解決系統(tǒng)復雜性這個難題,降低復雜性的通常做法就是分而治之,Dapr的最核心的設計就是Sidecar Pattern?+?Building Block,如下圖:
圖片來源:https://docs.microsoft.com/zh-cn/dotnet/architecture/dapr-for-net-developers/dapr-at-20000-feet
Sidecar Pattern: 通過職責分離與容器的隔離特性,降低應用程式的復雜度。
Building Block:? 類似于樂高搭積木方法,通過Dapr 提供的核心組件(Component),分離與抽象化系統(tǒng)架構。
Dapr 設計上幾乎和Bilgin Ibryam?提出的Multi-Runtime Microservices Architecture?不謀而合,它有幾個核心的設計點:
Sidecar
Building Block & Component
Service Invocation
Middleware
State
基于上面的這些核心設計,Dapr 有了多運行時微服務架構 的特性,以此延伸出底下的重要功能,或者說設計模式:
Security
Observability: tracing, metrics, logs and health
Pub / Sub / Batch Process
Actors
Secret Management
Config Management 正在開發(fā)中……
Sidecar
Sidecar是非常重要的云計算設計模式,下面這張圖是 Sidecar 與Microservice 之間搭配后形成多個服務的關系圖,這樣的結構形成了服務網(wǎng)格的概念, Dapr 通過配置的方式,動態(tài)生成Sidecar?,隨后伴隨著App,一組Dapr Sidecar + App 的組合稱為Dapr App
Dapr App 在K8s 里面的形態(tài)就是 Pod = (App_Container + Sidecar_Container)
同樣的概念,如果Dapr App跑在k8s外面,也就是自承載模式。在自承載模式下,微服務和 Dapr sidecar 在沒有容器業(yè)務流程協(xié)調(diào)程序(如 Kubernetes)的單獨本地進程中運行。
每個Dapr App 都通過Sidecar 溝通,在通信之前,Dapr App 要知道的是對方在哪?所以服務發(fā)現(xiàn)和服務調(diào)用是Dapr App 要解決的第一個問題,知道彼此在哪了,然后就是通信模式,Dapr 支持HTTP / gRPC 兩種通信模式。Dapr App 之間的默認的通信模式使用gRPC,也就是如果使用HTTP調(diào)用Dapr API,內(nèi)部服務之間的通信也會轉成gRPC。
gRPC 是一種新式的高性能框架,它通過?RPC?(遠程過程調(diào)用) 改進。gRPC 使用 HTTP/2 作為傳輸協(xié)議,該協(xié)議通過 HTTP RESTFul 服務提供顯著的性能增強,包括:
對通過同一連接發(fā)送多個并行請求的多路復用支持 - HTTP 1.1 將處理限制為一次處理一個請求/響應消息。
雙向全雙工通信,用于同時發(fā)送客戶端請求和服務器響應。
內(nèi)置流式處理,支持對大型數(shù)據(jù)集進行異步流式處理的請求和響應。
若要了解有關詳細信息,請查看適用于 Azure 電子書的.NET Cloud-Native中的?gRPC概述。
Dapr Sidecar 有了服務調(diào)用、服務發(fā)現(xiàn)和通信模式之后,定義出來了一個Building Block (構建塊)的概念,使用聲明的方式,定義多個組件Component 擴展Sidecar的能力,這些能力正是分布式系統(tǒng)需要面對的問題。
構建塊 和 組件
構建基塊封裝分布式基礎結構功能。可以通過 HTTP 或 gRPC API 訪問該功能,目前版本有如下構建塊。
Buiding Block 是每個 Dapr Sidecar 可以擴展的概念,每個 Block 由多個 Components 組成,開發(fā)者可以自行設計、擴展 Component,然后貢獻給社區(qū),這里集中了社區(qū)貢獻的組件?https://github.com/dapr/components-contrib。我們來看一下微軟的.NET團隊基于Dapr 設計的eshopondapr,圖中每個Dapr標示都是一個Component ,一共標記了六種:
基于這樣的設計,Dapr 把最核心的Component 提供了基于分布式系統(tǒng)的?最佳實踐 (Best Practice)和 設計模式(Design Patterns)
Input/Output Bindings:
全部列表:Supported external bindings
Pub / Sub:
全部列表:Supported pub/sub brokers?Middleware: Dapr 的一種特殊 Components,后面介紹。
Service discovery name resolution: Dapr 的特殊 Components,后面介紹。
State Stores
全部列表:Supported state stores
Secret Stores
全部列表:Supported secret stores
這些核心的設計可以通過代碼倉庫了解:
倉庫?https://github.com/dapr/components-contrib?是Dapr 官方開放的Component ,開發(fā)者可以通過 PR 提交來把 擴展的Component 貢獻給社區(qū),目前已經(jīng)有70 多個Components 可以使用,使用的時候要注意版本的階段性是在Alpha / Beta / GA,一定要做好風險評估。
服務調(diào)用和服務發(fā)現(xiàn)
這就是我們在微服務里面常說的服務治理,Dapr 作為一個分布式系統(tǒng),多個Dapr app怎么知道彼此的存在,通過什么方式進行溝通,這就是Dapr的服務治理要解決的問題,Dapr的服務發(fā)現(xiàn)機制,按照架構的不同方式(k8s還是自托管)有不同的實現(xiàn),官方文檔(https://docs.dapr.io/zh-hans/developing-applications/building-blocks/service-invocation/service-invocation-overview/)里的這張圖介紹了調(diào)用邏輯
服務 A 對服務 B 發(fā)起HTTP/gRPC的調(diào)用。
Dapr 使用?name resolution component?發(fā)現(xiàn) Service B’s 位置 取決于運行的環(huán)境?hosting platform.
Dapr 將消息轉發(fā)至服務 B的 Dapr 邊車
注: Dapr 邊車之間的所有調(diào)用考慮到性能都優(yōu)先使用 gRPC。僅服務與 Dapr 邊車之間的調(diào)用可以是 HTTP 或 gRPC
?
服務 B的 Dapr 邊車將請求轉發(fā)至服務 B 上的特定端點 (或方法) 。服務 B 隨后運行其業(yè)務邏輯代碼。
服務 B 發(fā)送響應給服務 A。響應將轉至服務 B 的邊車。
Dapr 將消息轉發(fā)至服務 A 的 Dapr 邊車。
服務 A 接收響應。
Dapr 命名有Namespace 概念,基本格式為FQDN
Dapr 的Service Invocation 支持 gRPC / HTTP 兩種方式,默認的 Service to Service 使用gRPC 通信。
Service to Service 使用mTLS 做傳輸層加密
支持 Service 的ACL,可以個別控制每個API 與Method 的操作
支持 Retry 機制
可以使用其他service discovery 實現(xiàn)
RR load balancing with mDNS
支持tracing 和 metric
問題空間涉及并發(fā)性。如果沒有Actor,則需要在代碼中引入顯式鎖定機制。
可以將問題空間分區(qū)為小、獨立和隔離的狀態(tài)和邏輯單元。
不需要低延遲的讀取Actor 狀態(tài)。? 因為Actor 操作是按順序執(zhí)行,不能保證低延遲讀取。
不需要在一組Actor 之間查詢狀態(tài)。跨Actor 的查詢效率低下,因為每個Actor 的狀態(tài)都需要單獨讀取,并且可能會導致不可預測的延遲。
服務治理:包含Service Invocation、Service Trusted and Authorization (服務的信任、認證與授權)、通信模式(HTTP / gRPC)、通信機制(Push / Pull)、狀態(tài)管理(State Machine)
運維:高可用、擴展機制、Log 處理、分布式追蹤、Metric
安全性:Data Encryption、Secret Management、KMS、Auth 集成
性能和可靠性:Rate Limit、降級、熔斷…
可擴展的架構
如何提升開發(fā)團隊的效能
這里面有很多核心的概念:
Middleware
和ASP.NET Core 支持通過 middleware 處理 HTTP request / response 完成一些 Cross-Cutting (AoP) 的功能,Dapr 也支持 Middleware 的概念,如下圖:
Dapr 允許通過鏈接一系列中間件組件來定義自定義處理管道。請求在路由到用戶代碼之前經(jīng)過所有已定義的中間件組件,然后在返回到客戶機之前,按相反順序經(jīng)過已定義的中間件,如下圖中所示。
Actors
Actor 模型 起源于Carl Hewitt ?在 1973 年提出的作為并發(fā)計算的概念模型,這種形式的計算會同時執(zhí)行多個計算。當時并沒有高度并行的計算機,但多核 Cpu 和分布式系統(tǒng)的最新進步使得Actor 模型 變得流行。在Actor 模型中,Actor 是一個計算和狀態(tài)獨立的單元。Actors 完全彼此隔離,它們永遠不會共享內(nèi)存。Actors 使用消息相互通信。當一個Actor 收到消息時,它可以更改其內(nèi)部狀態(tài),并將消息發(fā)送到其他 (可能是新的) Actors。
Actor模型使得編寫并發(fā)系統(tǒng)變得更簡單的,它提供了基于 turn-based 的 (或單線程) 訪問模型。多個Actors可以同時運行,但每個Actor 一次只處理一個接收的消息。這意味著,在任何時候,都可以確保在Actors 中最多有一個線程處于活動狀態(tài)。這使得編寫正確的并發(fā)系統(tǒng)和并行系統(tǒng)變得更加容易。
Dapr 的實現(xiàn)基于?項目 "Orleans" 中引入的虛擬Actor模式。對于虛擬Actor模式,不需要顯式的創(chuàng)建Actor。第一次將消息發(fā)送到Actor時,Actor將被隱式激活并放置在群集中的節(jié)點上。當不執(zhí)行操作時,Actor 會以靜默方式從內(nèi)存中卸載。如果某個節(jié)點出現(xiàn)故障,Dapr 會自動將激活的Actor 移到正常的節(jié)點。除了在Actor之間發(fā)送消息以外,Dapr Actor模型還支持使用計時器和提醒調(diào)度將來的工作。
雖然Actor模型 提供了很大的優(yōu)勢,但必須仔細考慮Actor的設計。例如,如果多個客戶端調(diào)用相同的Actor,則會導致性能不佳,因為Actor ?操作會按順序執(zhí)行。下面的檢查清單是是否適用于 Dapr Actor的一些標準:
滿足這些條件的一種設計模式非常好,就是?基于業(yè)務流程的 saga?或?流程管理器?設計模式。Saga 管理必須執(zhí)行的一系列步驟才能達到某些結果。Saga (或進程管理器) 維護序列的當前狀態(tài),并觸發(fā)下一步。如果一個步驟失敗,saga 可以執(zhí)行補償操作。利用Actor,可以輕松處理 saga 中的并發(fā),并跟蹤當前狀態(tài)。?EShopOnDapr 參考應用程序使用 saga 模式和 Dapr Actor來實現(xiàn)排序過程。
為了提供可伸縮性和可靠性,將在Actor服務的所有實例中對actor進行分區(qū)。Dapr placement ?服務負責跟蹤分區(qū)信息。啟動Actor 服務的新實例時,Sidecar 會將支持的Actor 類型注冊到placement 服務。placement 服務計算給定Actor 類型的更新分區(qū)信息,并將其廣播給所有實例。
總結
分布式架構的門檻比較高,需要考慮的問題很多,通常我們都需要考慮如下問題。
上述的這些東西,通常是一個有經(jīng)驗的、資深的軟件工程師,如何在資源有限的情況下,可以快速開發(fā)、容易測試,是很多技術人的痛點所在。
這些問題從個別來看,都有相當成熟的系統(tǒng),如果個別看,有很多現(xiàn)成的實踐可以參考。但是對于存在了幾十年的祖?zhèn)鞔a的系統(tǒng)架構而言,如果要進行微服務改造,往往都要傷筋動骨,讓技術主管和架構師傷透腦筋,往往要面對新舊技術的整合,同時也要面對現(xiàn)實的團隊需求的交互和對于新技術的學習門檻。對于開發(fā)應用程式的開發(fā)人員來講,滿足業(yè)務需求的開發(fā)已經(jīng)夠頭痛了,還要考慮這么多系統(tǒng)架構層面的東西,這種事是無法靠熱情填補的。Dapr 將一些經(jīng)過驗證的技術和最佳實踐帶到微服務開發(fā)中。它通過即插即用模型將90 年代的數(shù)據(jù)驅動的客戶端/服務器應用程序的操作,應用于現(xiàn)代云原生應用程序所需的最常見服務,讓我們集中于業(yè)務需求的開發(fā),而不需要考慮系統(tǒng)架構層面的東西 。
Dapr 正式發(fā)布已經(jīng)過去了半年時間了,現(xiàn)在最新版本是1.3.0.? 下圖是技術采用生命周期,在早期采用者和早期大眾的中間,有一個死亡之井,無法越過死亡之井,則死亡,Dapr已經(jīng)跨過了死亡之井,你可以采用Dapr了。
總結
以上是生活随笔為你收集整理的浅析 Dapr 里的云计算设计模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用 baget 搭建 nuget 私有
- 下一篇: .NET 6 中哈希算法的简化用法