rabbitmq之死信佇列的應用

2021-09-13 21:13:12 字數 3282 閱讀 8381

如果此教程對你有幫助,有錢的捧個錢場,沒錢的請捧個人場!

1、背景說明:

開發環境:sprint boot,rabbitmq,mysql,jdk1.8...

在預生產環境中,消費者消費訊息時出現了異常,後台不斷寫日誌,一天時間日誌檔案超過了30g,導致伺服器因磁碟空間不足而宕機!

2、原因分析:

1)rabbitmq的預設配置spring.rabbitmq.listener.default-requeue-rejected=true,訊息消費失敗,則重新放回佇列,再次消費時依然失敗,又被重新放回佇列,從而陷入死迴圈......後台不停地寫日誌;

2)消費者消費訊息的程式中沒有用try_catch_來捕獲可能出現的異常;

3、解決方案:

方案一:統一配置

## 訊息消費失敗,則丟棄訊息

spring.rabbitmq.listener.default-requeue-rejected=false 

方案二:新增訊息消費失敗監聽事件

listenercontainerconsume***iledevent

方案三:死信佇列

dead-letter-exchange

方案四:手動確認

autoack = true

本文主要**死信佇列的解決方案!

4、知識點簡介

dlx, dead-letter-exchange。利用dlx, 當訊息在乙個佇列中變成死信(dead message)之後,它能被重新publish到另乙個exchange,這個exchange就是dlx。訊息變成死信一般有一下幾種情況:

1)訊息被拒絕(basic.reject/ basic.nack)並且requeue=false;

2)消費訊息時程式出現了異常;

3)訊息過期(x-message-ttl);

4)佇列中有訊息數量超過了最大值(x-max-length);

5)佇列中的訊息容量超過了佇列的最大空間(x-max-length-bytes);

dlx也是乙個正常的exchange,和一般的exchange沒有區別,它能在任何的佇列上被指定,實際上就是設定某個佇列的屬性,當這個佇列中有死信時,rabbitmq就會自動的將這個訊息重新發布到設定的exchange上去,進而被路由到另乙個佇列,可以監聽這個佇列中訊息做相應的處理,這個特性可以彌補rabbitmq 3.0以前支援的immediate引數(可以參考rabbitmq之mandatory和immediate)的功能。

5、案例**

編碼步驟:

1)建立普通交換機;

2)建立普通佇列,設定佇列屬性x-dead-letter-exchange,與死信交換機繫結;設定佇列其他屬性...;

3)繫結普通佇列到普通交換機上;

4)建立死信交換機;

5)建立死信佇列;

6)繫結死信佇列到死信交換機上,並指定死信路由鍵;

生產者:

/** 生產者只需向交換機中傳送訊息 */

public class messageproducer

system.out.println("訊息發布成功");

channel.close();

connection.close();

} catch (ioexception e) catch (timeoutexception e)

}

普通資訊者:

/*  普通資訊者 */

public class commonconsumer

};channel.basicconsume(queuename, true,consumer);

} catch (ioexception e) catch (timeoutexception e)

}}

死信消費者:

/* 建立列信佇列消費者 */

public class dlxconsumer

};channel.basicconsume(dlxqueuename,true, consumer);

} catch (ioexception e) catch (timeoutexception e)

}}

6、結果展示:

7、在springboot demo中的**:

/* 配置死信佇列 */

/* 死信交換機 */

private static string dlxexchangename = "dlx_exchange";

/* 死信佇列 */

private static string dlxqueuename = "dlx_queue";

/* 死信路由鍵 */

private static string dlxroutingkey = "routingkey.dead";

/* 1、宣告死信交換機 */

@bean(name="dlxexchange")

public directexchange dlxexchange()

/* 2、宣告死信佇列 */

@bean(name="dlxqueue")

public queue dlxqueue()

/* 3、繫結死信佇列與死信交換機 */

@bean

binding bindingdlxexchangequeue(@qualifier("dlxqueue") queue dlxqueue, @qualifier("dlxexchange") directexchange dlxexchange)

/* 4、修改普通佇列的配置,訊息消費失敗後將路由到死信佇列中 */

@bean

public queue queue()

RabbitMQ之死信佇列 延遲佇列 優先順序佇列

從機制上看,rabbitmq除了有topic和queue的概念,發訊息的時候要指定訊息的key,這個key之後會做路由key使用 還有乙個概念叫做交換機exchange,exchange有四種,drdirect fanout topic header。就是說發訊息給rabbitmq時,訊息需要有個k...

RabbitMq死信佇列

死信交換機有什麼用呢?在建立佇列的時候 可以給這個佇列附帶乙個交換機,那麼這個佇列作廢的訊息就會被重新發到附帶的交換機,然後讓這個交換機重新路由這條訊息。通俗的說,就是訊息產生之後,因為設定了超時時間,在這段時間內訊息沒有被消費就會被扔到死信佇列裡面。交換機名稱 private static fin...

rabbitmq死信佇列

死信佇列 dlx dead letter exchange 利用dlx,當訊息在乙個佇列中變成死信 dead message 之後,它能重新publish到另外乙個exchange,這個exchange就是dxl 訊息變成死信的幾種情況 訊息被拒絕 basic.reject basic.nack 並...