如果此教程對你有幫助,有錢的捧個錢場,沒錢的請捧個人場!
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 並...