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