微服務信息同步方案(數據依賴一致性問題)

_ 作者:牛牛碼特_

juejin.cn/post/6844903924915240974

背景

微服務場景下需要同步信息的場景。

還是前文的栗子: 如下微服務

此時產品上有個需求,在支付管理端根據是否出賬搜索支付流水,而出賬是賬單服務的功能。所以這裏涉及到信息的同步,那麼,我們怎麼保證同步一定能成功呢(最終一致性)。

消費者

保證在隊列中的消息,一定會被消費。用白話來講,就是不停消費直到成功。

方式比較簡單:消息隊列都使用手動提交。處理完了,再保證提交。儘量遵循觸發 - 查詢機制,提供可重入性,即消息隊列只傳遞 id 這種非實質信息,收到之後再通過 rpc 查詢拉取完整數據來更新。

生產者

主要是發送消息到隊列這步的可靠性考量

方案一:淺嘗輒止

以遞增的時間間隔重試 5 次。如果失敗了,上報到日誌和告警,人工介入。同時,具體業務準備好重試的腳本。根據實時的情況進行處理。優點:

缺點:

方案二:內有波瀾

失敗之後,內存維護一個重試隊列,先由 5,10,20, 40, 80, 160, 320s 的間隔重試。之後以 5 分鐘一次的間隔請求。同時,也要打入日誌系統,告警通知。

優點:可靠性會比一高很多,在消息隊列故障 30 分鐘這種場景下,也能自動恢復。可以做成 package 的方式,方便接入。

缺點:

限制:

方案三:內有波瀾 plus

失敗之後,內存維護一個重試隊列,先由 5,10,20, 40, 80,160, 320s 的間隔重試。然後 append 到本地文件,同時以 5 分鐘一次的頻率做重試。重試完成之後,從磁盤中刪除對應信息。當服務重啓,從磁盤把數據導入內存即可。

優點:

缺點:

限制:

方案四:有備無患

實現任務重試微服務,該服務通過維護一張任務表,重試任務直到成功。相當於是消息隊列這個可靠中間件有問題,就丟給這個重試服務這個自己實現的 “中間件”。

優點:

缺點:

限制:

以上方案中,三,四基本能解決重試階段寫入消息隊列的可靠性問題。但針對另一個場景:正想寫本身服務就沒了的情況(比如 oom 導致服務被系統 kill 了) 還是不行。

方案五:先入爲主

要做變更之前,先寫入到消息同步微服務,告訴他要做什麼事(把什麼消息放入消息隊列),和流程最長執行時間,以及發給誰。該服務維護一張任務表,任務初始處於未激活狀態。

等業務做完要同步的時候,再 rpc 請求觸發激活。

任務管理微服務如果發現一個任務,超過最長執行時間沒有激活。就說明激活 rpc 失敗了,或者是服務崩潰,本身就沒做變更。此時,自動激活即可。

優點:完全可靠(事務可能還是會失敗,可靠指數據一定最終一致)。

缺點:

限制:

總結

推薦:方案三

推薦理由:成本不高,可靠性較強。可靠度 99.99%。(此處不論代碼本身 bug)

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/RMMOB8cLkNxz5_HTsMEOLA