微服務模式-同步與異步


了解同步和異步的不同類型的微服務模式,以及每種服務的優勢和取舍。

微服務是一種架構范例。在這種架構風格中,小型且獨立的組件可以作為一個系統協同工作。盡管其操作復雜性較高,但該范例已被迅速采用。這是因為它有助於將復雜的系統分解為可管理的服務。服務包含微觀層面的關注點,例如單一責任,關注點分離,模塊化等。

微服務模式是一系列博客。每個博客都將關注微服務的體系結構模式。它將說明可能性並概述適用的情況。所有這些都在考慮到各種系統設計約束之間的相互影響。

通過優銳課的java學習分享,了解到服務間通信和執行流程是分布式系統的基礎決策。本質上,它可以是同步的或異步的。兩種方法都有其取舍和優勢。該博客試圖詳細剖析各種選擇並理解其含義。

外型尺寸

每種實現方式都有權衡。 同時,正在考慮的系統可能有多種尺寸。 在這些約束條件下評估取舍可以幫助我們推理出方法和適用性。 系統的各個方面都會影響系統的執行流程和通信風格。 讓我們來看一些。

消費者

系統的使用者可以是外部程序,Web /移動界面,IoT設備等。使用者應用程序通常會與服務器同步處理,並期望接口能夠支持該服務器。 還期望用用於消費者的統一接口來掩蓋分布式系統的復雜性。 因此,我們的溝通方式必須讓我們為之便利。

工作流程管理

對於許多參與服務,業務流程的管理至關重要。它可以是隱式的,並且可以在每個服務處發生,因此保持分布在各個服務之間。或者,它可以是顯式的。協調器服務可以負責協調業務流程。

業務流程是兩件事的結合。工作流程規范,列出執行順序和對服務的實際調用。后者與參與服務遵循的通信范式緊密相關。溝通方式和執行流程驅動着協調器的實現。

第三種選擇是基於事件編排的設計。這通過每個服務綁定到的事件總線來替代協調器。

所有這些都是在系統中管理工作流程的機制。在本系列的后面,我們將詳細介紹工作流管理。但是,在評估和選擇交流范式時,我們將在當前上下文中考慮與它們相關的約束。

/寫頻率偏差

系統的讀/寫頻率可能是其體系結構中的關鍵因素。 大量讀取的系統期望大多數操作同步完成。 一個很好的例子是大規模運行的天氣預報服務的公共API。 替代地,繁重的寫入系統受益於異步執行。 一個示例就是一個平台,在該平台上,許多IoT設備不斷報告數據。 當然,兩者之間也有系統。 有時,由於讀寫偏斜,支持樣式很有用。 在其他時候,將讀取和寫入分為單獨的組件可能很有意義。

在研究各種方法時,我們需要保持對這些約束的了解。 這些維度將幫助我們提煉每種實現方式的適用性。

同步

同步通信是一種通信方式,在此方式中,呼叫者等待直到響應可用。這是一種突出且廣泛使用的方法。它的概念簡單性允許直接實現,使其非常適合大多數情況。

同步通信與HTTP協議緊密相關。但是,其他協議仍然是實現同步通信的同樣合理的方式。替代方法的一個很好的例子是RPC調用。每個組件都公開一個其他服務調用的同步接口。

入口點附近的攔截器攔截業務流程請求。然后,它將請求推送到下游服務。本質上,所有后續調用都是同步的。這些調用可以並行或順序進行,直到處理完成。系統內呼叫的處理方式可能會有所不同。協調器可以顯式協調所有呼叫。否則呼叫會在組件之間自然滲透。讓我們看一下幾種可能的機制。

變化

在同步系統中,架構可以采用幾種方法。 這是各種可能性的簡要概述。

去中心化和同步

分散和同步的通信樣式在入口點攔截流。 攔截器將請求轉發到下一步並等待響應。 此循環一直持續到下游,直到所有服務都已完成其執行。 每個服務可以順序或並行執行一個或多個下游服務。

盡管實現起來很簡單,但流細節仍保留在系統中。 這導致組件之間的耦合以執行流程。

呼叫在整個系統中保持同步。 因此,通信風格可以滿足同步消費者的期望。 由於工作流程具有分布式性質,因此該方法沒有靈活性的余地。 它不太適合易於更改的復雜工作流程。 由於對系統的每個請求都可以同時阻止服務,因此對於具有高讀寫頻率的系統而言,這不是理想的選擇。.

 

編排,同步和順序

同步通信的一種形式是使用中央協調器。 協調器將保留攔截服務。 它使用工作流定義處理傳入的請求,並將其轉發到下游服務。 每個服務依次反過來響應協調器。 在處理請求之前,協調器一直在對服務進行調用。

在開始列出的限制中,工作流管理在此方法中更加靈活。 工作流程更改僅對業務流程負責,並且具有靈活性。 由於通信是同步的,因此同步使用者可以在沒有中介組件的情況下進行通信。 但是,協調器將繼續保留所有活動請求。 與其他服務相比,這給協調器帶來了更多負擔。 它也容易成為單點故障。 這種體系結構的樣式仍然適用於重載系統

 

協調,同步和並行

對先前方法的一個小改進是使獨立請求並行進行。 這導致更高的效率和性能。 由於這種責任屬於編排領域,因此很容易做到。 工作流管理已經集中。 它只需要更改聲明即可區分並行調用和順序調用。

這可以允許更快地執行流。 使用較短的響應時間,協調器可以具有更高的吞吐量。

工作流管理比以前的方法更為復雜。 由於它同時提高了吞吐量和性能,因此仍然可能是一個合理的權衡。 所有這些,同時使消費者保持通信同步。 由於其同步特性,該系統對於重讀架構仍然更好。

 

權衡取舍

盡管同步調用更易於掌握,調試和實現,但在分布式設置中仍有一些折衷值得承認。

平衡容量

它需要故意平衡所有服務的容量。 一個組件上的臨時突發可能會使其他服務泛濫。 以異步方式,隊列可以減輕臨時突發。 同步通信缺少這種中介,需要在突發期間匹配服務容量。 否則,可能會導致級聯失敗。 替代地,諸如斷路器的彈性范例可以幫助減輕同步系統中的業務突發。

級聯故障的風險

同步通信使上游服務容易受到微服務架構中級聯故障的影響。 如果下游服務失敗或最差,則需要很長時間才能做出響應,資源可能會很快耗盡。 這可能會導致系統產生多米諾骨牌效應。 可能的緩解策略可能涉及一致的錯誤處理,合理的連接超時和強制執行SLA。 在同步環境中,不斷惡化的服務的影響會立即通過其他服務波動。 如前所述,可以通過實施bulkhead架構或使用斷路器來防止級聯錯誤。

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

參與服務的冗余和可用性需求可以通過在負載平衡器后面進行設置來解決。 這增加了每個服務的間接級別。 此外,每個服務都需要參與中央服務發現設置。 這使它可以推送自己的地址並解析下游服務的地址。

耦合

同步系統在一段時間內會表現出更緊密的耦合。 服務之間沒有抽象,便直接綁定到其他服務的契約。 這會在一段時間內形成強耦合。 對於合同中的簡單更改,所有權服務必須盡早采用版本控制。 從而增加了系統復雜度。 或者,它使與合同相關的所有消費者服務的變更都順勢而為。

使用諸如服務網格之類的新興體系結構范例,可以解決某些陳述的問題。 Istio,Linkerd,Envoy等工具可用於創建服務網格。 這個空間正在成熟並且仍然很有希望。 它可以幫助構建同步,解耦和容錯的系統。

異步

異步通信非常適合於分布式體系結構。 它消除了等待響應的需要,從而使兩個或多個服務的執行脫鈎。 異步通信的實現有幾種變體。 通過RPC(例如grpc)或通過中介消息總線直接調用遠程服務的例子很少。 協調的消息傳遞和事件編排都使用消息總線作為通道。

中央消息總線的優點之一是一致的通信和消息傳遞語義。 與服務之間的直接異步通信相比,這可能是一個巨大的優勢。 通常使用諸如消息總線之類的介質來促進跨服務的一致通信。 下面討論的異步通信的變體將采用中央消息管道

變化

異步通信可以更好地處理零星的流量。 體系結構中的每個服務要么生成消息,要么消費消息,或者兩者都做。 讓我們看看這種范例的不同結構風格。

編排的異步事件

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

通知組件可能期望事件觸發電子郵件或SMS。 由於其他服務所需要做的就是生成事件,因此看起來似乎是分離的。 但是,確實需要有人來決定通知和內容的類型。 兩種通知都可以根據傳入的事件信息做出該決定。 如果發生這種情況,那么我們已經在通知和上游服務之間建立了聯系。 如果上游服務將此作為有效負載的一部分包括在內,則它們仍會知道下游的流量。

即使這樣,事件編排也非常適合需要發生的隱式動作。 錯誤處理,通知,搜索索引等

它遵循分散的工作流程管理。 該體系結構可很好地用於大量寫入的系統。 缺點是同步讀取需要中介,並且工作流會分散在整個系統中。

編排,異步和順序

我們可以從協調的同步通信中借鑒一些方法。我們可以與中心的協調器建立異步通信。

每個服務都是中央消息總線的生產者和消費者。協調器的職責涉及將消息路由到其相應的服務。每個組件都使用傳入的事件或消息,並在消息隊列上返回響應。 Orchestrator使用此響應並進行轉換,然后再路由到下一步。該循環一直持續到指定的工作流達到系統中的最后狀態為止。

通過這種樣式,工作流程管理對於協調器是本地的。該系統適用於大量寫入流量。同步消費者必須進行調解。這是所有異步變體中普遍存在的東西。

在編排的系統中,舞蹈編排耦合問題的解決方案更為優雅。在這種情況下,工作流程與Orchestrator一起使用。豐富的工作流程規范可以捕獲諸如通知類型和內容模板之類的信息。工作流程的任何更改都將保留在Orchestrator服務中。

 

 

與編排和事件編排混合

另一個成功的變體是同時具有編排和事件編排的混合系統。 編排非常適合顯式流程執行,而編排可以處理隱式執行。 工作流中葉節點的執行可以是隱式的。 工作流規范可以促進特定步驟中事件的發出。 這可能導致執行諸如通知,索引編制等任務。 編排可以繼續推動顯式執行。

兩種方法的這種融合提供了兩全其美的方法。 雖然,但仍需要采取預防措施,以確保他們不會重疊職責,明確界限決定其職能。

總覽

異步體系結構樣式解決了同步系統具有的一些陷阱。 異步設置在臨時請求的情況下效果更好。 中央隊列允許服務趕上合理的請求積壓。 當許多請求在短時間內到達時或服務暫時中斷時,這很有用。

每個服務都作為使用者或生產者連接到消息隊列。 僅消息隊列需要服務發現。 因此,對中央服務發現解決方案的需求減少了。 另外,由於服務的多個實例連接到隊列,因此不需要外部負載平衡。 這樣可以避免負載均衡器引入的另一種間接級別。 它還允許服務無縫地線性擴展。

權衡取舍

本質上是異步的服務流可能很難通過系統。 采用異步通信的系統需要進行一些折衷。 讓我們來看一些。

更高的系統復雜度

異步系統往往比同步系統復雜得多。 但是,系統的復雜性以及對性能和規模的要求對於開銷是合理的。 一旦被采用,協調器和單個組件都需要包含異步執行。

/查詢需要中介

除非專門處理,否則同步使用者將受異步體系結構的最大影響。 使用者需要適應與異步系統一起工作,或者系統應該為使用者提供一個同步接口。

異步體系結構很適合寫繁重的系統。 但是,它需要中介才能進行同步讀取/查詢。 有幾種方法可以滿足這種需求。 每個人都有一定的復雜性。

同步包裝器

所有方法中最簡單的方法是在異步系統上構建同步包裝器。 這是可以調用下游異步流的入口點。 同時,它保持請求等待,直到響應返回或發生超時。 同步包裝器是有狀態的組件。 傳入請求將其自身與其所連接的服務器綁定在一起。 來自下游服務的響應需要到達原始請求正在等待的服務器。 對於分布式系統,尤其是大規模運行的系統,這不是理想的選擇。 但是,它很容易編寫且易於管理。 對於具有合理縮放和性能需求的系統,它可以滿足要求。 在進行更激烈的重組之前,應該考慮使用同步包裝器。

CQRS

CQRS是一種將讀取與寫入分開的體系結構樣式。 CQRS給系統帶來了大量的風險和復雜性。 非常適合大規模運行且需要大量讀寫操作的系統。 在CQRS體系結構中,數據從寫入數據庫流到讀取數據庫。 查詢在經過讀取優化的數據庫上運行。 讀/寫層是分開的,並且系統最終保持一致。 這兩層的優化是獨立的。 這樣的系統結構復雜得多,但擴展性更好。 此外,組件可以保持無狀態(與同步包裝器不同)。

 

雙重支持

在同步包裝程序和CQRS實現之間有中間立場。 每個服務/組件都可以支持同步查詢和異步寫入。 這對於中等規模的系統非常有效。 因此,讀取查詢可以在組件之間跳轉,以同步完成讀取。 另一方面,寫入系統將沿異步通道流動。 但是,這里需要權衡。 不可能同時針對讀寫進行系統優化。 這對於在高流量下運行的系統是有益的。

消息總線是故障的中心點

這不是權衡取舍,而是預防措施。 在異步通信方式中,消息總線是系統的骨干。 所有服務不斷從消息總線產生和消耗消息。 這使消息總線成為系統的致命弱點,因為它仍然是故障的中心。 消息總線支持水平縮放非常重要,否則它可能會違反分布式系統的目標。

最終一致性

異步系統最終可能是一致的。 這意味着即使系統已發出寫操作,查詢結果也可能不是最新的。 盡管這種權衡取舍可以使系統更好地擴展,但還是要考慮系統的設計和用戶體驗兩者。

混合

可以同時使用異步和同步通信。 完成后,這兩種方法之間的權衡將抵消其優勢。 系統必須交替處理兩種通信方式。 同步調用可以級聯降級和故障。 另一方面,異步通信將增加設計的復雜性。 以我的經驗,隔離地選擇一種方法對於系統設計會更有成果。

判決

馬丁·福勒(Martin Fowler)有一個很棒的博客,介紹了構建微服務的決策。 一旦確定,微服務架構就需要仔細考慮其執行流程樣式。 對於寫入而言,重型系統異步是使用異步同步包裝器的最佳選擇。 而對於繁重的系統,同步通信效果很好。

對於讀寫繁重但規模要求適中的系統,同步設計在使設計保持簡單方面將大有幫助。 如果系統具有很大的規模和性能需求,那么采用CQRS模式的異步設計可能是可行的方法。

 

> 喜歡這篇文章的可以點個贊,歡迎大家留言評論,記得關注我,每天持續更新技術干貨、職場趣事、海量面試資料等等
 > 如果你對java技術很感興趣也可以交流學習,共同學習進步。 
> 不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代

文章寫道這里,歡迎完善交流。最后奉上近期整理出來的一套完整的java架構思維導圖,分享給大家對照知識點參考學習。有更多JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java干貨


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM