c Rabbit 訊息確認機制

2021-10-01 01:34:31 字數 2782 閱讀 5288

不想看細節 直接看總結

1.網路出現問題,或通道問題,程式層將會引發錯誤,捕獲錯誤資訊即可發現訊息丟失

2.路由出現問題,訊息未被路由到佇列中。

有兩種方法可以獲得通知

第一種: 投遞訊息時mandatory 引數設定為true 如果訊息未被路由到佇列中將會引發 basic.return 事件

第二種: 配置交換機的備用交換機 alternate-exchange 訊息無法被路由時,訊息將投遞到備用交換機,備用交換機 使用扇形交換機繫結乙個佇列即可得到未被路由的訊息

兩者同時啟用的情況,並不衝突,第一種的條件是未被路由到佇列的時候才會觸發,如果使用第二種方法使訊息通過備用交換機到達了佇列,那麼basic.return 將不會觸發,如果 備用交換機繫結佇列,或者無法路由到佇列,將會觸發basic.return 事件

3.訊息到達佇列,由於佇列的x-message-ttl 引數導致訊息超時被刪

通過配置訊息佇列的引數 x-dead-letter-exchange(交換機) 與 x-dead-routing-key(路由鍵) 解決

當訊息超時被刪除時會被投遞到x-dead-letter-exchange交換機 使用 x-dead-routing-key路由鍵

4.訊息到達佇列,由於佇列的x-max-length 或者 x-max-length-bytes 的限制.

這時候有兩種情況:

第一種: x-overflow 引數為drop-head(這個是預設的): 將會使訊息佇列把前面的訊息刪除,以便加入新的訊息,

刪除的訊息捕獲,參照3

第二種:x-overflow 引數為reject-publish: 將使訊息佇列拒收超出範圍的訊息。

解決方案 使用生產者的confirm 模式, 這將引發訊息投遞失敗

5.消費者取出訊息後,消費者未及時消費,消費者宕機,使用消費者手動確認模式。(這可能引發新的問題。重複消費)

後面的都是廢話

如何保證訊息一定被消費者接收?

如果,傳送成功 + 接收成功 那麼就能保證訊息一定被消費者接收。

有些時候,我們希望訊息被及時處理(客戶端及時響應),那麼應該再加上訊息超時機制。當訊息處理超時時提示玩家伺服器繁忙(這種情況應該很少,還是可以接受的)

//開啟事務

channel.txselect();

//事務提交

channel.txcommit();

//事務回滾

channel.txrollback();

示例:

try  catch (exception e)
事務中,如果訊息無法路由到佇列,是會正常提交,也就是說事務無法保證訊息一定到達佇列,

只能保證訊息到達boker 與一致性。

事務的最重要的作用是其一致性。如果是單獨投遞一條訊息,使用此來確認,顯然毫無用處。

事務的缺點。慢!。

無法保證訊息一定到達訊息佇列。

單條訊息確認

try  catch (exception e)
多條訊息的確認

try  catch (exception e)
值得注意的是:channel.confirmselect() 每個通道只需要執行一次,後面都是處於確認模式,這是我一直理解錯誤的乙個問題

非同步確認模式

實現 basicacks 事件來確認訊息是否傳送成功

實現 basicnacks 事件來確認未傳送成功的訊息 佇列本身的條件限制 ,且溢位模式設定為 reject-publish ,將會接收到的訊息

非同步效率最高

使用confirm模式也無法獲取訊息是否到達佇列。

投遞訊息時使用 mandatory +basicreturn 事件 來確認訊息是否到達佇列

使用basicreturn 事件可以獲取到未能正確到達佇列的訊息。

宣告交換機時使用策略 alternate-exchange 設定備用路由,

當訊息無法被路由時將會投遞到備用路由也可以獲取到未正確到達佇列的訊息。

使用以上兩種方法 + confirm 模式/ 事務確認模式,可以確保訊息被送達到 訊息佇列

當訊息被送達訊息佇列後,訊息也可能被丟失,

1.有可能系統宕機, 使用佇列持久化可以解決此問題。(如果訊息很重要,,持久化廢效率)

2. 有可能設定了訊息超時時間,訊息一段時間未被消費將會被扔棄,宣告佇列時使用策略x-dead-letter-exchange 與 x-dead-routing-key 來獲取被扔棄的訊息。 被扔棄的訊息將會被投遞到 x-dead-letter-exchange交換機使用 x-dead-routing-key 路由鍵來投遞訊息。設定此選項可以獲取到超時的訊息。

3. 訊息有可能由於 x-max-length 與 x-max-length-byte 的限制被扔棄, x-overflow: 為 drop-head 的情況下,同樣的可以使用2號方式來解決

4. 佇列被刪除…這個沒辦法,自己控制好。

使用basicconsume 與 basicget 獲取訊息都有個乙個引數 noack,

noack =true 時表示,**執行完畢後訊息被自動確認,確認後訊息將會從訊息佇列中刪除

noack= false 時表示 訊息需要手動確認

使用basicack方法來確認一條或多條訊息,如果確認的訊息不存在 則會產生異常,要注意

使用basicnack方法來拒絕一條或多條訊息,requeue 表示是否重新入列。false 表示訊息雖然被拒絕確認但是不會重新回到佇列,true 表示會訊息會被重新回到佇列中

使用basicreject方法拒絕一條訊息,requeue 表示是否重新入列。

訊息確認機制

每一次提交和請求的時候都會降低吞吐量 少用 三種模式 txselect 用於將當前channel設定為 事務 transation模式 txcmmit 提交事務 txrollback 回滾事務 用例 生產者 消費者 生產者confirm模式的原理 該模式的好處是什麼?該模式是非同步的,能提高吞吐量。...

Publisher的訊息確認機制

在前面的文章中提到了queue和consumer之間的訊息確認機制 通過設定ack。那麼publisher能不到知道他post的message有沒有到達queue,甚至更近一步,是否被某個consumer處理呢?畢竟對於一些非常重要的資料,可能publisher需要確認某個訊息已經被正確處理。在我們...

RabbitMQ實戰 訊息確認機制之訊息的正確消費

上節中我們講了如何確保訊息的準確發布,今天我們來看看如何確保訊息的正確消費。在之前的基礎上我們對消費者 倉庫服務 進行完善。所以,首先我們將ack的方式設定為手動 spring rabbitmq host xx port 5672 username x password x listener dir...