Rabbitmq 配置死信队列
消息有三种情况会成为死信
TTL
(time to live)时间超出,消息过期- 队列达到了最大设置长度(
x-max-length
),超出的消息成为死信 - 被
nack
并且未设置重回队列的消息,或者重新投递到了最大次数
死信队列的配置
app:
rabbitmq:
# 队列定义
queue:
user: user-queue
dead: user-dead-queue
# 交换机定义
exchange:
user: user-exchange
dead: user-dead-exchange
- 声明死信队列的Exchange
/**
* 死信交换机声明
* @param deadLetterExchange
* @return
*/
@Bean
public Exchange userDeadExchange(@Value("${app.rabbitmq.exchange.dead}") String deadLetterExchange) {
return ExchangeBuilder
.topicExchange(deadLetterExchange)
.durable(true)
.build();
}
- 声明死信队列的Queue
/*
* 死信消息队列 死信消息路由的队列
* @return
*/
@Bean
public Queue userDeadQueue(@Value("${app.rabbitmq.queue.dead}") String userDeadQueue) {
return QueueBuilder
.durable(userDeadQueue)
.build();
}
- 建立死信队列Exchange与死信队列的Queue
/**
* 死信队列绑定死信交换机
* @return
*/
@Bean
public Binding userDeadLetterBinding(Queue userDeadQueue, Exchange userDeadExchange) {
return BindingBuilder
.bind(userDeadQueue)
.to(userDeadExchange)
.with("user-dead-letter.*")
.noargs();
}
- 配置死信队列与自己的队列建立关系
@Bean
public Queue userQueue(@Value("${app.rabbitmq.queue.user}") String userQueueName
, @Value("${app.rabbitmq.exchange.dead}") String deadLetterExchange) {
return QueueBuilder
.durable(userQueueName)
//设置队列最大长度
.withArgument("x-max-length", 10)
//死信交换机声明
.withArgument("x-dead-letter-exchange", deadLetterExchange)
//死信消息的路由key
.withArgument("x-dead-letter-routing-key", "user-dead-letter.routingkey")
//消息过期时间设置 超出时间未消费成为死信
.withArgument("x-message-ttl", 60000)
.build();
}
userQueue中配置了:队列最大长度
,死信交换机绑定
,死信息消息routekey
,消息过期时间
如果消息超出10条未被消费,多出的会进入死信队列,超出60秒未被消息的也会进入死信队列。
定义一个Sender
package com.tangzq.send;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author tangzq
* @date 2020/4/8
*/
@Component
public class Sender {
@Autowired
RabbitTemplate rabbitTemplate;
@Value("${app.rabbitmq.exchange.user}")
String userExchangeName;
/**
* 发送消息100条 超出的90条进入死信队列
*/
public void sendMore(){
int i = 0;
while (i < 100){
i++;
CorrelationData correlationData = new CorrelationData("messageId" + i);
rabbitTemplate.convertAndSend(userExchangeName, "user.random", "{'msg':'message'}", correlationData);
}
}
}
测试方法发送100条消息
很明显,user-queue只有10条,还有90条进入了死信队列,此时再等60秒不作任何处理,等user-queue中的消息过期,也会进入死信队列