Spring Boot系列 死信佇列

2021-09-07 20:20:46 字數 3662 閱讀 3676

在說死信佇列之前,我們先介紹下為什麼需要用死信佇列。

如果想直接了解死信對接,直接跳入下文的"死信佇列"部分即可。

我們還是基於上篇《spring boot系列——7步整合rabbitmq》的demo**來說。

...

listener:

type: ******

******:

acknowledge-mode: auto

concurrency: 5

default-requeue-rejected: true

max-concurrency: 100

...

其中

acknowledge-mode

該配置項是用來表示訊息確認方式,其有三種配置方式,分別是none、manual和auto。

none意味著沒有任何的應答會被傳送。

manual意味著監聽者必須通過呼叫channel.basicack()來告知所有的訊息。

auto意味著容器會自動應答,除非messagelistener丟擲異常,這是預設配置方式。

default-requeue-rejected

該配置項是決定由於***丟擲異常而拒絕的訊息是否被重新放回佇列。預設值為true。

我一開始對於這個屬性有個誤解,我以為rejected是表示拒絕,所以將requeue-rejected連起來是拒絕重新放回佇列,後來查了資料明白這個屬性的功能才想起來rejected是個形容詞,其表示的應該是被拒絕的訊息

所以如果該屬性配置為true表示會重新放回佇列,如果配置為false表示不會放回佇列。

下面我們看看acknowledge-mode引數和default-requeue-rejected引數使用不同的組合方式,rabbitmq是如何處理訊息的。

對於receiver類新增了一行**,該**模擬丟擲異常

該配置不會確認訊息是否正常消費,所以在控制台沒有丟擲任何異常。通過在rabbitmq管理頁面也沒有看到重新放回佇列的訊息

同樣該配置不會確認訊息是否正常消費,所以在控制台沒有丟擲任何異常。而且即使default-requeue-rejected配置為true因為沒有確認所以也沒有看到重新放回佇列的訊息

該配置需要手動確認訊息是否正常消費,但是**中並沒有手動確認,個人理解是因為沒有收到ack,所以訊息又回到了佇列中。

該配置採用自動確認,從結果來看,是自動確認了。

從控制台列印的結果可以看出receiver方法執行了3次,分別是前面兩條放回佇列的訊息以及這次傳送的訊息,所以3條訊息都消費了。

同時因為default-requeue-rejected設定為false,所以即使消費丟擲異常,也沒有將訊息放回佇列。

該配置同樣採用自動確認,從結果看出,沒有丟擲異常(這塊也不是很理解),且因為default-requeue-rejected設定為true,所以訊息重新回到佇列。

綜上羅列這麼多情況只為說明有些情況下,如果訊息消費出錯,因為配置問題導致訊息丟失了。這在很多情況下是要命的,比如使用者支付的訂單號,如果因為拋異常等原因直接丟失是很要命的。

所以,我們需要有乙個確保機制,能夠保證即使失敗的訊息也能儲存下來,這時候死信佇列就排上用場了。

死信佇列的整個設計思路是這樣的

生產者 --> 訊息 --> 交換機 --> 佇列 --> 變成死信 --> dlx交換機 -->佇列 --> 消費者

下面我們通過網上的乙個簡單的死信佇列的實現看看如何使用死信佇列。

@bean("deadletterexchange")

public exchange deadletterexchange()

@bean("deadletterqueue")

public queue deadletterqueue()

@bean("redirectqueue")

public queue redirectqueue()

/*** 死信路由通過 dl_key 繫結鍵繫結到死信佇列上.

** @return the binding

*/@bean

public binding deadletterbinding()

/*** 死信路由通過 key_r 繫結鍵繫結到死信佇列上.

** @return the binding

*/@bean

public binding redirectbinding()

注意那麼如何模擬生成乙個死信訊息呢,可以在傳送到dl_queue的訊息在10秒後失效,然後**到替補佇列中,**實現如下

public void sendmsg(string content) ;

rabbittemplate.convertandsend("dl_exchange", "dl_key", content, messagepostprocessor);

}

執行結果如下

訊息首先進入dl_queue,5秒後失效,被**到redirect_queue中。

SpringBoot 整合RbbitMQ佇列3踩坑

1 找不到佇列 2019 07 03 13 11 11.106 warn 11944 ctaskexecutor 1 o.s.a.r.listener.blockingqueueconsumer failed to declare queue hello 2019 07 03 13 11 11.11...

Spring Boot 系列教程

spring boot 系列教程 spring boot 快速入門教程 spring boot 整合swagger文件 spring boot 整合mybatis框架 spring boot 實現mybatis分頁 spring boot 整合druid資料來源 spring boot 實現myba...

Spring Boot乾貨系列總綱

博主16年認識sping boot,17年才開始學習。自己學習的時候也查閱了很多資料,也看到很多優秀的部落格,但是整體上感覺沒有我想象中的那麼強大,一是版本有點舊了,大多是1.4版本的,博主自己看的時候已經1.5了。二是網上資料太多,質量參差不齊。每次查資料都要在海量資源中去挑選自己想要的好累啊。所...