消息隊列-如何保證消息沒有重復消費?

面試題

如何保證消息沒有重復消費?或者說,如何保證消息消費的冪等性?

考察緣由

消息消費,肯定就要考慮到消息是否被重復消費?能不能避免重復消費?或者重復消費了也別造成系統異常可以嗎?這個是 MQ 領域的基本問題,其實本質上還是問你使用消息隊列如何保證冪等性,這個是你架構里要考慮的一個問題。

面試題剖析

一、重復消費產生的問題描述

因為消息發送是基于網絡發送的,假設網絡延遲或者網絡卡頓,消息發送機制多次重試,消息重復發送的問題不可避免的發生。要直接避免不重復發送基本太難,因為網絡環境無法預知,還會使程序復雜度加大,因此默認允許消息重復發送。因此無論是點對點,還是發布/訂閱模型,都可能出現生產者發送多條一樣的數據到MQ,此時就會出現重復數據。

二、如何保證消息不被重復消費

基于以上問題描述, MQ 自己保證發送的消息不重復,這就需要我們開發來保證的。

2.1、ActiveMQ

消費者接收到消息時,將消息對象進行MD5加密,作為消息唯一性。如果發現messageObj(發送到mq的數據)已經存在,則忽略,進而保證消息不被重復消費。

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("已經有相同消息存在,忽略此消息!!! 【MESSAGE_ID】=" + t.getMessageId() +",【MESSAGE_TYPE】=" + t.getMessageType());

return 0;// 已經有相同的消息

}

冪等性:聯想到之前數學學習的冪等性,即使公式:f(x)=f(f(x)) 能夠成立的數學性質。用在編程領域,則意為對同一個系統,使用同樣的條件,一次請求和重復的多次請求對系統資源的影響是一致的。而計算機冪等性,直白講就是,就一個數據,或者一個請求,給你重復來多次,你得確保對應的數據是不會改變的,不能出錯。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容