MQ消費端在接收到MQ消息之后按照業(yè)務(wù)key(uuid)進行防重,達到消費的冪等性。
業(yè)務(wù)場景
用戶在使用白條優(yōu)惠劵打白條支付訂單后,如果用戶整單退款,需要給用戶補發(fā)優(yōu)惠劵。白條異步處理系統(tǒng)監(jiān)聽白條退款MQ消息進行整單退退劵操作。對于一筆訂單,整單退之后,用戶的優(yōu)惠劵只能補發(fā)一次。因此需要對MQ消費做防重冪等操作。
消費冪等的必要性
因為網(wǎng)絡(luò)會發(fā)生抖動,MQ消費端和生產(chǎn)端都可能會出現(xiàn)超時,這樣MQ就會出現(xiàn)重復(fù)發(fā)送和重復(fù)消費的情況,因此需要做到消費冪等。防止因此可能產(chǎn)生的資產(chǎn)損失。
整單退退劵的冪等
異步處理系統(tǒng)在接收到退款消息之后,會判斷當(dāng)前訂單是否已經(jīng)整單退款,如果已經(jīng)整單退款,首先會恢復(fù)用戶的參與次數(shù)(庫存),然后會寫退款流水記錄(refund_record)。這兩個步驟的操作是一個事務(wù)。退款流水記錄的'uuid'字段用來防重(加唯一索引),'uuid'的生成規(guī)則為'userId' + 'orderId'。這樣在MQ重試或者并發(fā)時spring會拋出DuplicateKeyException。我們捕獲這個異常,如果是這個異常,默認(rèn)MQ消費成功。這樣就可以做到MQ消費的冪等性。簡單地說,就是通過數(shù)據(jù)庫的唯一索引來保證MQ消費的冪等。
流程圖如下:

整單退流程圖