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

背景

微服務場景下須要同步信息的場景。網絡

仍是前文的栗子: 以下微服務 app

  • 支付服務:負責完成支付操做,其中有支付流水數據。
  • 帳單服務:指定時間生成帳單給用戶,其中有帳單流水數據。

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

消費者

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

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

生產者

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

方案一:淺嘗輒止

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

  • 簡單,能解決瞬間的網絡抖動形成的失敗。

缺點:blog

  • 可靠性低。在消息隊列故障30分鐘這種場景下,沒法自動恢復,同時從日誌撈取信息,也不是特別方便。

方案二:內有波瀾

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

優勢:可靠性會比一高不少,在消息隊列故障30分鐘這種場景下,也能自動恢復。能夠作成package的方式,方便接入。事務

缺點:

  • 服務重啓或者機器掛了,消息就丟了。

限制:

  • 消息處理須要遵循觸發-查詢機制

方案三:內有波瀾plus

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

優勢:

  • 可靠性會比一高不少,在消息隊列故障30分鐘這種場景下,也能自動恢復,能夠作成包的方式。
  • 具備比較強的通用型

缺點:

  • 增長了和磁盤打交道的邏輯,引入了文件io。

限制:

  • 消息處理須要遵循觸發-查詢機制

方案四:有備無患

實現任務重試微服務,該服務經過維護一張任務表,重試任務直到成功。至關因而消息隊列這個可靠中間件有問題,就丟給這個重試服務這個本身實現的「中間件」。

優勢:

  • 可靠性會比一高不少,在消息隊列故障30分鐘這種場景下,也能自動恢復。
  • 具備比較強的通用性。

缺點:

  • 成本變高,須要額外服務。同時,若是服務也掛了,仍是得依賴上報。(固然,上報也可能掛了)

限制:

  • 消息處理須要遵循觸發-查詢機制

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

方案五:先入爲主

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

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

任務管理微服務若是發現一個任務,超過最長執行時間沒有激活。就說明激活rpc失敗了,或者是服務崩潰,自己就沒作變動。此時,自動激活便可。

優勢:徹底可靠(事務可能仍是會失敗,可靠指數據必定最終一致)。

缺點:

  • 開發成本比較大,同時會增長消息調用。
  • 增長一個節點,事務失敗得可能性更高。

限制:

  • 消息處理須要遵循觸發-查詢機制

總結

推薦:方案三

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

相關文章
相關標籤/搜索