詳細解讀微服務的兩種模式

歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~html

本文來自雲+社區翻譯社,由用戶1196457編譯。數據庫

微服務是一種架構範例。在這種架構中,多個小型獨立組件協同工做,從而構成一個系統。儘管它的操做複雜性較高,但這種範式已經被迅速採用。這是由於它有助於將複雜的系統分解爲可管理的服務。這些服務更關注微觀層面的問題,包括單一責任,關注點分離,模塊化等。性能優化

微服務模式是一個系列博客。每篇博文都將聚焦一種微服務的架構模式,分析其可行性並概述它們適用的場景。全部這一切都要遵照各系統間相互制約的設計約束。服務器

服務間通訊和執行流程是分佈式系統的基礎,它能夠是同步的也能夠是異步的。這兩種方法都有其利弊,本博客試圖詳細剖析各類選擇並分析其影響。微信

維度

每種實現方式均可以從多種維度進行權衡。從這些維度對權衡點和系統約束進行評估,有助於咱們分析其可行性和適用性。每種實現方式都有折衷。與此同時,考慮中的系統可能有各類各樣的維度。根據這些限制評估取捨能夠幫助咱們推斷方法和適用性。系統的各個維度都會影響系統的執行流程和通訊方式,下面咱們來看看其中的一些維度。架構

消費者

系統的消費者能夠是外部程序,網頁/手機接口,物聯網設備等。消費者應用程序一般會同步處理服務器,並指望接口支持。用消費者的統一接口掩蓋分佈式系統的複雜性也是可取的,必要條件是,咱們的通訊方式選擇能帶來便利。併發

工做流管理

業務工做流貫穿多個服務,所以,業務工做流的管理相當重要。它能夠是隱含的,而且能夠發生在每一個服務上,所以仍然分佈在各個服務中。換言之,它能夠是明確的。協調器服務能夠承擔協調業務流程的責任。編排是二者的結合。工做流規範規定了執行順序和對服務的實際調用。協調器與參與服務遵循的通訊範式緊密相關。通訊風格和執行流程推進了協調器的實現。負載均衡

第三個選項是基於事件編排的設計,經過一個將全部服務綁定的事件總線來代替編排器。異步

全部這些都是系統中的工做流管理機制,咱們將在本系列的後續篇章詳細介紹工做流程管理。在咱們評估和選擇通訊方式時,咱們會考慮當前上下文中與其相關的約束條件。分佈式

讀/寫頻率誤差

系統的讀/寫頻率多是其體系結構中的關鍵因素。一個讀取繁重的系統須要大部分操做同步完成。一個很好的例子就是大規模運營的天氣預報服務的公共API。或者,寫入繁重的系統可從異步執行中受益。一個例子就是一個平臺,無數物聯網設備都在不斷報告數據。固然,它們之間也有系統。因爲讀寫偏斜,有時候傾向於一種風格是有用的。在其餘時候,將讀取和寫入拆分爲單獨的組件多是有意義的。

在咱們審視各類方法時,咱們須要保持這些約束。這些維度將幫助咱們提取每種實現方式的適用性。

同步

同步通訊是調用方等待響應可用的通訊方式,是一個突出並獲得普遍使用的方法。簡單且直觀的概念使其適用於大多數狀況。

同步通訊與HTTP協議密切相關。可是,其餘協議仍然是實現同步通訊的合理方式。另外一個很好的例子是RPC調用,每一個組件都公開一個其餘服務所調用的同步接口。

入口點附近的攔截器攔截業務流程請求,而後將請求推送到下游服務,全部的後續調用本質上都是同步的。這些調用能夠是並行或順序的,直處處理完成。系統內的調用處理可能會有不一樣的方式。一個編排者能夠顯式調度全部的調用,或者調用能夠跨組件有機地滲透。下面咱們看看幾個可能的機制。

變化

在同步系統中,架構能夠採用幾種方法,如下簡要說明各類方法的可行性。

去中心化和同步

去中心化的同步通訊方式在入口點攔截流量,攔截器將請求轉發到下一步並等待響應,該循環一直下行,直到全部服務都已完成執行,每一個服務能夠順序或並行執行一個或多個下游服務。

雖然實現很簡單,但流程細節分佈在整個系統中,從而致使組件之間的耦合。

這些調用在整個系統中保持同步。所以,這種通訊方式能夠知足同步消費者的指望。因爲分佈式工做流的性質,該方式缺乏靈活性,並不適用於常常更改的複雜工做流。因爲對系統的每一個請求均可能阻塞服務,所以對於讀/寫頻率高的系統來講,這並不理想。

編排、同步和順序

同步通訊的一種變體帶有中央編排器,編排器仍然是攔截服務。它處理傳入的工做流定義請求並將其轉發到下游服務,並接受響應(以下圖所示)。在處理請求過程當中,編排器一直在對服務進行調用。

在初始約束固定的狀況下,工做流管理在這種方法中更加靈活。工做流更改對編排器來講仍然是本地化的,並保有必定的靈活性,因爲通訊是同步的,因此同步消費者能夠在沒有中介組件的狀況下進行通訊。可是,編排器須要持續保持全部活動請求,這使得編排器比其餘服務承擔更重的責任,也容易致使單點故障。這種風格的架構仍然適合讀取繁重的系統。

編排,同步和並行

在以前的方法基礎上的一個小改進是使獨立請求能夠併發,這能夠得到更高的效率和性能。因爲這個責任屬於編排器,因此很容易作到。工做流管理已經集中,須要作的只是更改聲明以區分並行和順序調用。這能夠提升流程執行速度,經過縮短響應時間,協調器能夠得到更高的吞吐量。

工做流管理比之前的方法更復雜,但它仍然多是一個合理的折衷方案,由於它能夠提升吞吐量和性能並同時保持消費者的通訊同步。因爲其同步特性,該系統對於讀取型架構來講仍然更好。

權衡

儘管同步調用更易於掌控,調試和實現,但在分佈式環境中實施則須要一些權衡。

平衡能力

它要求有意平衡全部服務的能力。一個組件上的流量激增可能淹沒其餘服務請求。在異步通訊中,隊列能夠緩解流量激增。同步通訊缺乏這種中介,須要服務容量在流量激增期間進行匹配。若是作不到這一點,可能會出現級聯故障。另外,像斷路器這樣的彈性範例能夠幫助緩解同步系統中的流量激增。

級聯故障的風險

同步通訊使上游服務在微服務架構中容易出現級聯故障。若是下游服務出現故障或最壞狀況,則須要很長時間才能迴應,資源會很快耗盡。這可能會致使系統產生多米諾骨牌效應。可能的緩解策略可能涉及一致的錯誤處理,合理的超時時間以及執行服務質量保障協議。在同步環境中,一個服務會當即影響到其餘服務。如前所述,經過實施艙壁架構斷路器可防止級聯錯誤。

增長負載平衡和服務發現開銷

經過將參與服務放置在負載均衡器後面能夠解決其冗餘和可用性需求。這增長了每一個服務的隔離級別。此外,每項服務都須要加入中央服務發現設置,這容許它推送它本身的地址並解析下游服務的地址。

耦合

同步系統會在一段時間內表現出更緊密的耦合。服務之間沒有抽象,服務直接和其餘服務的合同綁定。這在一段時間內產生了強烈的關聯。對於合同中的簡單更改,擁有的服務不得不在早期採用版本控制。它增長了系統的複雜性,或者會致使與合同相關的全部消費者服務的變化。

隨着服務網格等新興架構範例的出現,有可能解決一些陳述的問題。IstioLinkerd特使等工具,容許服務網格建立。這個社區正在成熟而且充滿但願,它能夠幫助構建同步的,解耦的和容錯的系統。

異步

異步通訊很是適合分佈式體系結構。它不須要等待響應,從而將兩個或多個服務的執行分開。異步通訊的實現有幾種方式,經過RPC(例如,grpc)或經過中介消息總線直接調用遠程服務就是一些例子。編排消息傳遞和事件編排都使用消息總線通道。

中央消息總線的一個優勢是一致的通訊和消息傳遞語義。這給服務間的直接異步通訊帶來了巨大的便利。咱們一般使用像消息總線這樣的媒介來保證跨服務通訊的一致性。下面將基於使用中央消息管道的假設來討論的異步通訊的種類。

變體

異步通訊能夠更好地處理流量激增。體系結構中的每一個服務都會生成消息,消費消息或執行二者。咱們來看看這種範式的不一樣變體。

異步事件協同

在這種方法中,每一個組件監聽中央消息總線並等待事件,事件的到來是執行的信號,執行所需的任何上下文都是事件有效負載的一部分,觸發下游事件是每一個服務所擁有的責任。基於事件的體系結構的目標之一是將組件分離,不幸的是,須要在設計層面知足這種需求。

通知組件接受到事件時可能電子郵件或SMS發送。因爲全部其餘服務須要作的事情是生產事件,所以它看起來多是彼此分離的。可是,確實須要有組件承擔決定通知類型和內容的責任,通知能夠根據傳入的事件信息作出該決定,若是發生這種狀況,咱們就已經創建了通知和上游服務之間的耦合。若是上游服務將此做爲有效負載的一部分,則他們仍然感受到下游的流量。

即使如此,事件協同也很是適合須要發生的隱式操做。好比錯誤處理,通知,搜索索引等。

這種體系結構遵循分散的工做流程管理。該體系結構適合寫入繁重的系統。缺點是同步讀取須要協調,而且工做流會在系統進行廣播。

編排、異步和順序

咱們能夠從咱們的協調同步通訊方法中借鑑一些。咱們能夠經過中央編排器創建異步通訊。

每項服務都是中央消息總線的生產者和消費者。編排器的職責是將消息路由到他們相應的服務。每一個組件消費一個傳入事件或消息,並在消息隊列上生成響應。編排器消耗此響應並進行轉換,而後再前進到下一步。該循環繼續,直到指定的工做流程達到系統中的最後一個狀態。

在這種風格下,工做流管理對於編排器來講是本地的。這種系統在處理寫入流量很大時有很好的表現,同步消費者須要調解。這在全部異步通訊變體中都很流行。

在編排系統中,協同耦合問題的解決方案更加優雅。在這種狀況下,工做流工做在編排器上,豐富的工做流規範能夠捕獲通知類型和內容模板等信息,對工做流程的任何更改都保留在編排器服務中。

編排和事件協同混合使用

另外一個成功的變體是具備編排和事件協同的混合系統。編排很是適合顯示的工做流執行,而協同能夠處理隱式執行。在工做流程中執行葉節點多是隱含的,工做流規範能夠促進在特定步驟中發生事件,這可能會致使執行任務,如通知,索引等等,編排能夠繼續推進顯式執行。

這兩種方法的融合提供了近乎完美的方案,雖然仍須要採起預防措施以確保它們不會責任重疊,而且明確邊界以決定它們的功能。

概述

異步風格的體系結構解決了同步體系結構系統所具備的一些缺陷。異步結構在處理突發大量請求時表現更好。中央隊列容許服務遇上合理的請求積壓,當不少請求在短期內出現或者服務暫時關閉時,這是很是有用的。

每一個服務都以消費者或生產者的身份鏈接到消息隊列,只有消息隊列須要服務發現。所以,對中央服務發現解決方案的需求不那麼緊迫。此外,因爲服務的多個實例鏈接到隊列,所以不須要外部負載平衡,這能夠防止負載平衡器引入致使的隔離級別提高。它還使服務可以無縫線擴展。

權衡

本質上是異步的服務流可能很難經過系統進行跟蹤。採用異步通訊的系統會有一些折衷,咱們來看看其中的一些權衡點。

更高的系統複雜性

異步系統每每比同步系統複雜得多。然而,系統的複雜性和性能以及規模的要求是合理的開銷。一旦採用協調器和單個組件,就須要接受異步執行。

讀取/查詢須要中介

除非專門處理,不然同步消費者受異步體系結構的影響最大。要麼消費者適應異步系統的工做,要麼系統爲消費者提供同步接口。

異步架構很是適合寫入繁重的系統。可是,它須要協調讀取/查詢同步,有幾種方法來管理這種需求,每種都有必定的複雜性。

同步包裝

全部方法中最簡單的是在異步系統上構建同步包裝。這是一個能夠調用下游異步流程的入口點。同時,它保存等待的請求,直到響應返回或發生超時。同步包裝是一個有狀態的組件。傳入的請求將本身綁定到它所在的服務器上。來自下游服務的響應須要到達原始請求正在等待的服務器。這對分佈式系統來講並不理想,尤爲是那種大規模運行的系統。可是,編寫起來很簡單,並且易於管理。這種方法符合具備合理的縮放和性能需求的系統的需求。在進行更爲劇烈的重構以前,能夠考慮同步封裝。

CQRS

CQRS是一種將讀取與寫入分離的架構風格。CQRS給系統帶來了大量的風險和複雜性,它很是適合大規模運行並須要大量讀取和寫入的系統。在CQRS體系結構中,數據從寫數據庫流向讀數據庫,查詢在讀取優化的數據庫上運行,讀/寫層是分開的,系統保持最終一致性。兩個層的優化是獨立的。這樣的系統結構更復雜,但能夠具備更大的規模。並且,組件能夠保持無狀態(與同步包裝不一樣)。

雙重支持

在同步包裝器和CQRS實現之間有一箇中間地帶,每一個服務/組件均可以支持同步查詢和異步寫入,這適用於中等規模運行的系統。因此讀取查詢能夠在組件之間跳轉以完成同步讀取。另外一方面,寫入系統將流入異步通道。這裏有一個權衡,對系統的讀和寫進行獨立優化是不可能的,或者,這對於在高流量下運行的系統是有益的。

消息總線是故障的中心點

這不是一種折衷,而是一種預防措施。在異步通訊方式中,消息總線是系統的支柱,全部的服務都不斷地從消息總線上生產和消費。這使得消息總線成爲系統的致命弱點, 由於它仍然是故障的中心點。消息總線支持橫向擴展很是重要,不然它可能違背分佈式系統的目標。

最終一致性

異步系統能夠是最終一致性,這意味着查詢結果可能不是最新的,即便系統已經發布了寫入。雖然這種權衡可讓系統更好地擴展,但也須要同時考慮系統設計和用戶體驗。

混合

能夠同時使用異步和同步通訊,但這兩種方法的權衡會壓倒他們的優點。一方面,系統必須交換處理兩種通訊風格,同步調用會致使級聯降級和失敗。另外一方面,異步通訊會增長設計的複雜性。根據個人經驗,選擇單一方式對於系統設計來講更加富有成效。

結語

馬丁福勒有一個關於如何構建微服務的偉大博客。一旦決定構建微服務架構,須要仔細審議其執行流程風格。對於寫入繁重系統來講,帶有同步包裝的異步系統是最佳選擇。而對於讀取繁重系統,同步通訊就很好。

對於讀寫繁重,但具備適度規模要求的系統而言,同步設計將大大簡化設計。若是一個系統具備顯著的規模和性能需求,那麼使用CQRS模式的異步設計是一種可選方案。

騰訊雲分佈式微服務

騰訊分佈式微服務TSF圍繞應用和微服務的PaaS平臺,提供服務全生命週期管理能力和數據化運營支持,提供多維度應用、服務、機器的監控數據,助力服務性能優化;擁抱 Spring Cloud 開源社區技術更新和K8s容器化部署。

詳見 https://cloud.tencent.com/product/tsf

問答
微服務架構:跨服務數據共享如何實現?
相關閱讀
基於微服務的 Abixen 平臺中的領域驅動設計方法 
次世代的會話管理項目 Spring Session
使用Akka HTTP構建微服務:CDC方法

此文已由做者受權騰訊雲+社區發佈,原文連接:https://cloud.tencent.com/developer/article/1152802?fromSource=waitui

歡迎你們前往騰訊雲+社區或關注雲加社區微信公衆號(QcloudCommunity),第一時間獲取更多海量技術實踐乾貨哦~

相關文章
相關標籤/搜索