消息隊(duì)列-如何保證消息沒有重復(fù)消費(fèi)?

面試題

如何保證消息沒有重復(fù)消費(fèi)?或者說(shuō),如何保證消息消費(fèi)的冪等性?

考察緣由

消息消費(fèi),肯定就要考慮到消息是否被重復(fù)消費(fèi)?能不能避免重復(fù)消費(fèi)?或者重復(fù)消費(fèi)了也別造成系統(tǒng)異??梢詥??這個(gè)是 MQ 領(lǐng)域的基本問題,其實(shí)本質(zhì)上還是問你使用消息隊(duì)列如何保證冪等性,這個(gè)是你架構(gòu)里要考慮的一個(gè)問題。

面試題剖析

一、重復(fù)消費(fèi)產(chǎn)生的問題描述

因?yàn)橄l(fā)送是基于網(wǎng)絡(luò)發(fā)送的,假設(shè)網(wǎng)絡(luò)延遲或者網(wǎng)絡(luò)卡頓,消息發(fā)送機(jī)制多次重試,消息重復(fù)發(fā)送的問題不可避免的發(fā)生。要直接避免不重復(fù)發(fā)送基本太難,因?yàn)榫W(wǎng)絡(luò)環(huán)境無(wú)法預(yù)知,還會(huì)使程序復(fù)雜度加大,因此默認(rèn)允許消息重復(fù)發(fā)送。因此無(wú)論是點(diǎn)對(duì)點(diǎn),還是發(fā)布/訂閱模型,都可能出現(xiàn)生產(chǎn)者發(fā)送多條一樣的數(shù)據(jù)到MQ,此時(shí)就會(huì)出現(xiàn)重復(fù)數(shù)據(jù)。

二、如何保證消息不被重復(fù)消費(fèi)

基于以上問題描述, MQ 自己保證發(fā)送的消息不重復(fù),這就需要我們開發(fā)來(lái)保證的。

2.1、ActiveMQ

消費(fèi)者接收到消息時(shí),將消息對(duì)象進(jìn)行MD5加密,作為消息唯一性。如果發(fā)現(xiàn)messageObj(發(fā)送到mq的數(shù)據(jù))已經(jīng)存在,則忽略,進(jìn)而保證消息不被重復(fù)消費(fèi)。

String md5 = MD5.encrypt(t.getMessageObj());

List list =super.query("SELECT * FROM message_mq WHERE MD5=? AND STATUS>=? AND STATUS<=? ",this, md5, MessageMq.MessageStatus.MESSAGE_STATUS_NORMAL, MessageMq.MessageStatus.MESSAGE_STATUS_HANDLE);

if (list !=null && list.size() >0) {

log.info("已經(jīng)有相同消息存在,忽略此消息!!! 【MESSAGE_ID】=" + t.getMessageId() +",【MESSAGE_TYPE】=" + t.getMessageType());

return 0;// 已經(jīng)有相同的消息

}

冪等性:聯(lián)想到之前數(shù)學(xué)學(xué)習(xí)的冪等性,即使公式:f(x)=f(f(x)) 能夠成立的數(shù)學(xué)性質(zhì)。用在編程領(lǐng)域,則意為對(duì)同一個(gè)系統(tǒng),使用同樣的條件,一次請(qǐng)求和重復(fù)的多次請(qǐng)求對(duì)系統(tǒng)資源的影響是一致的。而計(jì)算機(jī)冪等性,直白講就是,就一個(gè)數(shù)據(jù),或者一個(gè)請(qǐng)求,給你重復(fù)來(lái)多次,你得確保對(duì)應(yīng)的數(shù)據(jù)是不會(huì)改變的,不能出錯(cuò)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容