异步发送,那消息可靠性怎么保证?
消息丟失可能發生在生產者發送消息、MQ本身丟失消息、消費者丟失消息3個方面。
生產者丟失
生產者丟失消息的可能點在于程序發送失敗拋異常了沒有重試處理,或者發送的過程成功但是過程中網絡閃斷MQ沒收到,消息就丟失了。
由于同步發送的一般不會出現這樣使用方式,所以我們就不考慮同步發送的問題,我們基于異步發送的場景來說。
異步發送分為兩個方式:異步有回調和異步無回調,無回調的方式,生產者發送完后不管結果可能就會造成消息丟失,而通過異步發送+回調通知+本地消息表的形式我們就可以做出一個解決方案。以下單的場景舉例。
1、下單后先保存本地數據和MQ消息表,這時候消息的狀態是發送中,如果本地事務失敗,那么下單失敗,事務回滾。
2、下單成功,直接返回客戶端成功,異步發送MQ消息
3、MQ回調通知消息發送結果,對應更新數據庫MQ發送狀態
4、JOB輪詢超過一定時間(時間根據業務配置)還未發送成功的消息去重試
5、在監控平臺配置或者JOB程序處理超過一定次數一直發送不成功的消息,告警,人工介入。
一般而言,對于大部分場景來說異步回調的形式就可以了,只有那種需要完全保證不能丟失消息的場景我們做一套完整的解決方案。
MQ丟失
如果生產者保證消息發送到MQ,而MQ收到消息后還在內存中,這時候宕機了又沒來得及同步給從節點,就有可能導致消息丟失。
RocketMQ分為同步刷盤和異步刷盤兩種方式,默認的是異步刷盤,就有可能導致消息還未刷到硬盤上就丟失了,可以通過設置為同步刷盤的方式來保證消息可靠性,這樣即使MQ掛了,恢復的時候也可以從磁盤中去恢復消息。
雖然我們可以通過配置的方式來達到MQ本身高可用的目的,但是都對性能有損耗,怎樣配置需要根據業務做出權衡。
消費者丟失
消費者丟失消息的場景:消費者剛收到消息,此時服務器宕機,MQ認為消費者已經消費,不會重復發送消息,消息丟失。
RocketMQ默認是需要消費者回復ack確認,而kafka需要手動開啟配置關閉自動offset。
消費方不返回ack確認,重發的機制根據MQ類型的不同發送時間間隔、次數都不盡相同,如果重試超過次數之后會進入死信隊列,需要手工來處理了。(Kafka沒有這些)
?
總結
以上是生活随笔為你收集整理的异步发送,那消息可靠性怎么保证?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么使用mq?具体的使用场景是什么?
- 下一篇: RocketMQ实现原理