第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

1. 前言

上個小節(jié)中我們介紹了 RabbitMQ 中如何防止消息丟失,即保證消息發(fā)送的 At Least Once 性質(zhì),除此之外,如何防止消息被重復消費,即保證消息消費的 Exactly Once 性質(zhì),也是業(yè)務(wù)邏輯中需要考慮的問題。

2. 消息消費順序

面試官提問:業(yè)務(wù)中使用了 RabbitMQ 消息隊列,如何保證消息的順序消費?

題目解析

保證消息的順序消費是業(yè)務(wù)場景下經(jīng)常面臨的挑戰(zhàn),可能在面試中會涉及到一些實戰(zhàn)場景,例如電商的下單邏輯,在用戶下單之后,會發(fā)送創(chuàng)建訂單和扣減庫存的消息,我們需要保證扣減庫存在創(chuàng)建訂單之后執(zhí)行。

在MQ層面支持消息的順序消費是一件開銷很大的操作,例如使用事務(wù),所以除非特定場景,一般不在 RabbitMQ 消息傳輸?shù)讓又С猪樞?。在上層即應用層處理業(yè)務(wù)邏輯是常規(guī)操作,有兩種通用解決方案:

(1)同步發(fā)送消息:將消息發(fā)送從異步模式切換為同步模式,例如先發(fā)送創(chuàng)建訂單消息,當創(chuàng)建訂單的下游消費者發(fā)送ACK確認成功消費后,再發(fā)送扣減庫存的消息;
(2)消息實體增加冗余字段:例如增加 version(版本號)、 msg_id(消息id),保證在扣減庫存時,對應 msg_id 的訂單已經(jīng)創(chuàng)建成功,實戰(zhàn)中配合Redis等緩存協(xié)助判斷。

3. 消息重復消費

面試官提問:RabbitMQ 如何保證消息不會被重復消費?

題目解析:

所有的消息隊列都要保證同一條消息不會被重復消費,RabbitMQ 重復消費消息的可能場景主要有兩種:

(1)生產(chǎn)者重復發(fā)送消息:生產(chǎn)者在往消息隊列發(fā)送消息時,發(fā)生了網(wǎng)絡(luò)抖動,生產(chǎn)者沒有收到確認信號,但是實際上消息隊列已經(jīng)收到了消息,超過一定時間后生產(chǎn)者會重新發(fā)送消息,這時一條消息被發(fā)送了兩次;
(2)消費者重復接受消息:消費者成功消費消息后,發(fā)生了網(wǎng)絡(luò)抖動,消息隊列沒有收到確認信號,超過一段時間后會重新給消費者投遞相同的消息,同一條消息即存在被消費兩次的可能。

通用解決方案是在消息實體中添加全局唯一的id,例如 msg_id(消息ID),在業(yè)務(wù)邏輯層保證消息的冪等性,具體參考步驟:

(1)消費者在收到消息之后,根據(jù) msg_id 從緩存/數(shù)據(jù)庫中查詢是否存在已有消息;
(2)如果不存在已有消息,那么消費之后,將 msg_id 對應的消息實體或者序列化對象寫入緩存/數(shù)據(jù)庫;
(3)如果存在已有消息,說明這條消息已被消費過,丟棄消息并且打一條告警日志。

并且可以根據(jù)重復消費的容忍程度以及性能要求選擇使用緩存還是使用數(shù)據(jù)庫,如果對判斷的速度要求高,可以使用 Redis 作為緩存;如果對判斷的穩(wěn)定性和魯棒性要求高,使用數(shù)據(jù)庫存儲消息實體,同時將 msg_id 作為數(shù)據(jù)庫表的唯一鍵,插入重復記錄一定會拋出異常,避免數(shù)據(jù)庫因為并發(fā)問題產(chǎn)生臟數(shù)據(jù),保證了消息消費的不可重復性。

4. 小結(jié)

本章節(jié)介紹了 RabbitMQ 中最常見的重復發(fā)送消息的實際場景,并且給出了添加全局唯一 ID 的通用性解決方案,候選人需要理解通過全局 ID 解決重復消息的核心邏輯,準備時間充裕的情況可以在本地環(huán)境編碼實現(xiàn)上述流程。