簡體   English   中英

如何在故障情形下基於事件的消息驅動的微服務架構中恢復狀態

[英]How to restore state in an event based, message driven microservice architecture on failure scenario

在微服務架構的背景下,消息驅動,異步,基於事件的設計似乎越來越受歡迎(參見此處此處的一些示例,以及Reactive Manifesto - 消息驅動特性 )而不是同步(可能是REST)基於)機制。

考慮上下文並想象一個過度簡化的訂購系統,如下所示:

訂購系統

和以下消息流程:

  • 訂單來自某些來源(網絡/移動等)
  • 訂單服務接受訂單並發布CreateOrderEvent
  • InventoryService對CreateOrderEvent做出反應,執行一些庫存事務並在完成后發布InventoryUpdatedEvent
  • 然后,Invoice服務對InventoryUpdatedEvent做出反應,發送發票並發布EmailInvoiceEvent

所有服務都很好,我們很樂意處理訂單......每個人都很高興。 然后,庫存服務由於某種原因而下降😬

假設事件總線上的事件流向“非阻塞”庄園。 即消息被發布到一個中心主題,並且如果沒有服務正在從中讀取消息,則不會堆積在隊列中(我想要傳達的是事件總線,如果事件在總線上發布,它將會流“直通”而不排隊 - 忽略此時使用的消息平台/技術)。 這意味着如果庫存服務停機5分鍾,那么CreateOrderEvent在此期間通過事件總線現在“消失”或者看不到庫存服務,因為在我們過度簡化的系統中,沒有其他系統感興趣在那些事件中。

我的問題是:庫存服務(以及整個系統)如何以不丟失/未處理訂單的方式恢復狀態?

好問題! 所以這里基本上有三種力量在起作用:

  1. 如果服務中斷,則可能已經錯過的任何事件都需要重播以保持一致
  2. 事件,因為它們發生在“時間”,有一個“這發生在那之前”命令他們
  3. 可能有(但不一定是)另一方有興趣監督一系列事件,以確保達到某種狀態。

對於#1和#2,您需要某種持久的事件日志。 傳統的消息隊列/主題可能會提供這一點,但您必須考慮消息可能無序處理到事務/異常/故障行為的情況。 像Apache Bookkeeper,Apache Kafka,AWS Kinesis等更簡單的日志可以按順序存儲/保存這些類型的事件,並讓消費者按順序處理/過濾掉重復/分區流等。

對我來說,3號是狀態機。 但是你實現狀態機真的取決於你。 基本上,這個狀態機基於其他系統中的事件跟蹤發生了什么事件並轉換到允許狀態(並且可能參與發射事件/命令)。

例如,當您嘗試關閉房屋時,真實世界的用例可能看起來像“托管”。 托管公司不僅處理金融交易,而且通常他們與房地產經紀人合作,協調訂購文件,簽署文件,轉移資金等。每次事件后,托管變為“等待買方簽名”狀態“等待賣家簽名”到“等待資金”到“封閉式成功”......他們甚至有這些事件發生的最后期限等,如果錢沒有被轉移到“交易結束”,可以轉移到另一個州沒完成“還是什么的。

在您的示例中,此狀態機將偵聽pub / sub通道並捕獲此狀態,運行計時器,發出其他事件以進一步涉及所涉及的系統等。它本身並不一定“編排”它們,但它確實跟蹤在必要時進展並執行超時和補償。 這可以作為流處理器,作為流程引擎實現,或者(最好的起點)只是一個簡單的“托管”服務。

實際上,如果“托管”服務出現故障或失敗,它將如何處理重復項,如何處理意外事件(如果它處於狀態狀態,它如何導致重復事件等等),那么實際上還有更多需要跟蹤的情況......但是希望足以開始。

我將給建築師一個答案,而不是深入細節。 我希望你不介意。

第一個建議是將所有概念分離:事件,消息,總線和/或隊列和異步。 如果您尚未確定用於實施總線的軟件,這將為您提供可能性。

從架構的角度來看,如果您需要“必須交付”類型的方案,您將在服務失敗時保留消息。 是的,您可能需要在系統中進行某種清理,因為事情會發生,但首先要關注有保證的交付問題。 我看到了兩個可以擴展的基本選項(可能有更多,但這些足以開始考慮問題)。

  • 清單服務處理從隊列中提取消息。 在此方法中,服務將重新啟動並查找任何消息。
  • “公共汽車”保證交付。 當出現故障時,它會等待服務重新啟動(可以ping通以查看是否再次啟動,或者服務是否可以重新注冊為訂戶(企業服務總線類型的方案)。

僅僅因為系統是異步的並且基於事件並不意味着你無法實現某種類型的保證交付。 一個隊列是一個選項(你似乎放棄了這個想法?),但是一個總是失敗並且一旦訂閱者再次出現就重試的總線是另一個。 你可以堅持不懈地堅持下去。

另一個問題是消息使用什么令牌以使它們同步回到手頭的業務功能,但我認為你在系統中以某種方式處理了這個。 您可能沒有的唯一概念是讓系統都尊重令牌,並在發生故障時返回消息時尊重其他系統。

請注意,從商業角度來看,異步通信並不意味着在接觸點發生火災和遺忘。 您可以在不使用每個信息位的異步方法的情況下返回消息。 我在這里的意思是庫存系統啟動可以處理消息並發送到UI端的應用程序,它可以返回“忘記它,你太慢了”,所以事務返回到其原始狀態(不存在?) 。

我沒有足夠的信息(或時間?)來建議哪種方法最適合您的架構,因為細節仍然有點過高,但希望這會激起一些想法。

希望這是有道理的,因為我在ADHD狀態下基本上做了大腦到鍵盤操作。 ;-)

首先,我們正在建立的系統有一個目的,通常是通過讓客戶滿意並回歸來增加收入和利潤。 因此, 必須處理源自客戶行為的消息/事件(假設,該公司正在優先考慮客戶體驗......因為願意投入資金)。

順便說一句,客戶 - 企業關系是整個系統中我們希望緊密耦合的關系,與內部所有其他關系不同。 所以在這種情況下,它是“權威”而不是自治的一個例子。 我們保證以品牌為代表的SLA。

但是,消息重要性的范圍應該比“必須交付”更細粒度,而不是反映優先級。 類似於變得更細粒度的功能(微服務)。 稍后會詳細介紹

因此,確保消息/事件由訂閱者處理的目標可以通過確保服務永不停機(如MS Orleans中的“虛擬角色”概念)或通過將更多錯誤處理邏輯放入傳遞機制來實現。

后一種選擇似乎更加集中/耦合,而不是自主/解耦。 但是,如果您認為服務並非始終可用(我們應該這樣做),那么您需要考慮刪除關於“瞬態”消息的其他假設。

第一個選項決定如何保證服務的可用性,從而保證擁有服務的敏捷團隊,同時通過輸出指標來衡量性能。

此外,如果作為封裝功能的服務保證了高服務水平(“永不停機”),則可以通過調整消息優先級以及將新服務和事件注入到整個系統(=企業)的結果中來持續調整。系統。

另一個重要方面是同步體系結構(=基於調用堆棧)提供了三個特性,即異步體系結構(事件驅動)為了減少依賴性而沒有展示:協調,延續和上下文(參見Hohpe,“ call stack“,2006)。

我們仍然需要為業務層面的客戶提供這些功能,因此需要在其他地方進行介紹。 Hohpe建議,松散耦合系統行為的配置和監控需要額外的代碼層,這與核心業務功能同樣重要(復雜事件處理能夠理解事件之間的關系)

這些現代CEP系統必須處理大量數據,不同的速度,結構和正確性水平,可以在現代數據處理和大數據系統(例如Spark)之上實現,用於理解,決策和優化兩者敏捷團隊(以改善他們的服務)和管理團隊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM