微服務模式(一):事件處理

我是獸獸,從事雲計算的健身萌妹紙,不定期更新5G&IoT內容,更多好貨可關注公號:5G物聯網世界。 

“事件處理”是一種模型,它允許您通過使用消息隊列來解耦您的微服務。雖然消息隊列處理沒有適合所有人的解決方案,但是這裡有一些處理錯誤和管理事務的好模式,它們將加深您對最佳實踐微服務體系結構設計的理解。

“事件處理”是一種模型,它允許您通過使用消息隊列來解耦您的微服務。您不是直接連接到某個服務(該服務可能在已知位置,也可能不在),而是通過Redis、Amazon SQS、RabbitMQ、Apache Kafka和整個主機的其他源廣播和偵聽隊列中的事件。

“消息隊列”是一個高度分佈式和可伸縮的系統。它應該能夠處理數百萬條消息,這樣我們就不必擔心它不可用。在隊列的另一端,將有一個“使用者”偵聽指向它的新消息。當它接收到這樣的消息時,它處理該消息,然後將其從隊列中刪除。

由於事件處理模式的異步特性,需要以可編程的方式處理故障。

事件處理,至少一次交付

第一個基本同步機制是請求交付。我們將消息添加到隊列中,然後等待隊列的確認(ACK),以讓我們知道消息已經收到。當然,我們不知道消息是否已經傳遞,但是接收ACK應該足以通知用戶並繼續。

接收服務始終可能無法處理消息。潛在的原因包括直接失敗,或者接收服務中的錯誤,或者添加到隊列中的消息沒有按照接收服務能夠理解的方式進行格式化。我們需要獨立處理這兩個問題。

處理錯誤

分佈式系統出現問題並不罕見。這是基於微服務的軟件設計背後的邏輯的一個重要部分。

在上面的場景中,如果無法處理有效的消息,一種標準方法是重試處理消息,通常會有延遲。重要的是,每當我們無法處理一條消息時,都要附加錯誤,以便構建出錯歷史,這可以在事件後分析和重構過程中提供真正有用的見解。這樣的歷史記錄還使我們能夠了解我們嘗試處理消息的次數,因為在超過這個閾值之後,我們不想繼續重試。我們需要將此消息移動到第二個隊列或死信隊列,我們將在接下來討論這個隊列。重要的是要設置這樣的歷史生成機制,並在您的微服務體系結構中構建一種處理錯誤的方法,使其不會阻塞隊列或產生級聯的下游影響。

使用死信隊列調試失敗

處理消息之後從隊列中刪除消息是一種常見的做法。死信隊列的目的是為了檢查這個隊列上的失敗消息,以幫助我們調試系統。因為我們可以將錯誤細節附加到消息主體,所以我們知道錯誤是什麼,並且知道歷史記錄應該放在哪裡。

處理冪等事務

雖然現在許多消息隊列除了提供至少一次的傳遞之外,還提供最多一次的傳遞,但是在處理大量消息時,後者仍然是最好的選擇。為了處理接收服務可能兩次獲得消息這一事實,該服務需要能夠使用自己的邏輯來處理這種重複。確保消息不會被處理兩次的常見方法之一是在一個事務表中記錄消息ID,記錄已經處理的消息,並使用一個參數說明是否將丟棄該消息。

處理消息的排序

在處理重試失敗時,常見的問題之一是接收的消息順序錯誤或順序不正確,這會將不一致的數據轉儲到數據庫中。為了避免這種問題的方法之一是利用事務表和存儲消息dispatch_date除了ID。當接收服務得到了消息,它不僅可以檢查如果當前消息被處理它可以檢查最近的消息,如果沒有丟棄它。

利用原子事務

這是在將遺留系統轉換為微服務時最常見的問題。在存儲數據時,數據庫可以是原子的——也就是說,所有操作都發生或不發生。分佈式事務不能提供與數據庫中相同的事務類型。當數據庫事務的一部分失敗時,我們可以回滾事務的其他部分。通過使用此模式,我們只會在進程成功時從隊列中刪除消息,以便在出現故障時繼續重試。即使事務的初始狀態是不完整的,這也會使我們的事務在理想情況下最終變得一致。

不幸的是,沒有適合所有人的消息傳遞解決方案。我們需要定製與服務的操作條件匹配的解決方案。

我將在下一篇文章中繼續討論這個問題,該文章將深入探討“服務發現”。


分享到:


相關文章: