消息發送一致性
微服務架構下,需要通過網絡進行通信,就自然引入了數據傳輸的不確定性,也就是CAP原理中的P-分區容錯,而這里的消息發送一致性是可靠消息的保證。
生成消息的業務動作與消息發送的一致(e.g: 如果業務操作成功,那么由這個業務操作所產生的消息一定會成功投遞出去,否則就丟失消息)
如上圖,保證消息發送一致性的一般流程如下:
- Producer先把消息發送給消息中間件服務,消息的狀態標記為
待確認,這個狀態並不會被Consumer消費,對於長期待確認的消息,消息中間件會調用Producer的查詢接口,查看最新狀態,根據結果決定是否刪除消息。 - Producer執行完業務操作后,向消息中間件服務,發送確認消息
- 這時消息的狀態會被更改為
待發送(可發送) - Consumer監聽並接收待發送狀態的消息,執行業務處理
- Consumer業務處理后,向消息中間件服務發送
ACK,確認消息已經收到(消息中間件服務將從隊列中刪除該消息)
消息的ACK確認流程中,任何一個環節都可能會出問題!
對未ACK的消息,采用按規則重新投遞的方式進行處理(很多MQ都提供at least once的投遞,持久化和重試機制),一般還會設置重發的次數, 超過次數的消息會進入dead letter queue,等待人工干預或者延后定時處理。
業務接口的冪等性
消息的重復發送會導致業務接口出現重復調用的問題,主要原因就是消息沒有及時收到ACK確認導致的, 那如何實現冪等性設計呢?
在實際的業務場景中, 業務接口的冪等性設計,常結合查詢操作一起使用,
比如根據唯一標識查詢消息是否被處理過, 或者根據消費日志表,來維護消息消費的記錄。
保證最終一致性的模式
- 可查詢模式,任何一個服務操作都提供一個可查詢接口,用來向外部輸出操作執行的狀態,下游Consumer可以通過接口得知服務操作執行的狀態,然后根據不同的狀態做不同的處理操作(執行或者取消), 該模式對業務接口有一定侵入性。
- 補償模式, 有了查詢模式,我們能夠知道操作的具體狀態,如果處於不正常狀態,我們可以
修正操作中出現的問題,或許是重新執行,或許取消已經完成的操作,通過修復是的整個分布式系統達到最終一致。 - 最大努力通知模式, 在調用支付寶交易接口或微信支付接口時,一般會在回調頁面和接口里,解密參數,然后調用系統中更新交易狀態相關的服務,將訂單更新為付款成功。同時,只有當回調頁面中輸出了success字樣或者標識業務處理成功相應狀態碼時,支付寶才會停止回調請求。否則,支付寶會每間隔一段時間后,再向客戶方發起回調請求,直到輸出成功標識為止。
