环境:Spring Boot2.3.10 + RabbitMQ 3.8.12 + Erlang 23.2.5
死信队列介绍
来自队列的消息可以是“死信”消息;也就是说,当发生以下任何事件时,可以重新发布到
exchange:
- 当消费者使用basic.reject or basic.nack 方法并且requeue 参数设置为false时。
- 消息设置了TTL参数(建立队列时设置了x-message-ttl参数),消息过期;或消息被丢弃,因为其队列超过了长度限制。
注意:队列的过期不会导致其中的消息死信(建立队列时设置了x-expires参数)。
死信交换机也是正常的交换机,可以是任何类型的交换机。
在创建队列的时候可以指定x-dead-letter-exchange,x-dead-letter-routing-key(可选)参数指定当发生上述2个情形时就行重写转发到死信交换机上。
准备环境
- 新建正常业务所需的交换机及队列
建立business-exchange类型为topic的交换机
建立dead-exchange类型为fanout类型的交换机;死信交换机
建立business-queue队列
这里设置了x-dead-letter-exchange参数,值为上面建立的死信交换机。这里并没有设置x-dead-letter-routing-key参数,因为我们的死信交换机类型为fanout,该类型与routing-key无关。
相应的交换机与队列进行绑定。
测试
方式1:消息消费端调用basic.reject or basic.nack方法时
发消息接口:
@GetMapping("/sendDeadLetter")
public Object sendDeadLetter(String msg) {
ms.sendDeadLetter(msg) ;
return "success" ;
}
public void sendDeadLetter(String msg) {
logger.info("准备发送消息:{}", msg);
rabbitTemplate.convertAndSend("business-exchange", "be.1", msg) ;
}
接收消息:
@Component
public class MessageListener {
@RabbitListener(queues = { "bussiness-queue" })
@RabbitHandler
public void listener1(Message message, Channel channel) {
System.out.println("接受到消息.....income");
byte[] body = message.getBody();
MessageProperties mps = message.getMessageProperties();
String content = new String(body, Charset.forName("UTF-8"));
try {
// 模拟 拒绝消息的情况
if ("1".equals(content)) {
System.out.println("拒绝消息:1") ;
channel.basicReject(mps.getDeliveryTag(), false);
return ;
}
System.out.println("接受到消息来自交换机: 【" + mps.getReceivedExchange() + "】, 队列:【" + mps.getConsumerQueue()+ "】:\n\t\t内容: " + content);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
} catch (Exception e) {
e.printStackTrace();
try {
channel.basicReject(mps.getDeliveryTag(), false);
} catch (IOException e1) {
e1.printStackTrace() ;
}
}
}
}
这里模拟当接收到的消息为“1”时拒绝消息。
发送正常消息:
发送拒绝消息:
查看消息队列
消息被转发到了死信队列。
方式2:设置消息的TTL参数,设置过期时间。
重新建立business-queue队列。
x-message-ttl:消息过期时间,单位为毫秒。这里设置10秒后过期。
绑定到交换机,如下图
把接收消息的监听器注释了,我们这里不进行消息的消费。等到消息过期后消息是否会被转发到死信队列中。
发送消息前查看队列情况
发送消息
10s后:
消息被转发到了死信队列,我们可以查看dead-queue队列中的消息
方式3:设置消息队列消息数的最大个数。
删除bussiness-queue队列,重新建立
设置x-max-length值为3,最大只能保存3条消息,超过的被转发到死信队列。
再次与business-exchange进行绑定
先连续发送3条消息:
发送前消息队列消息情况:
发送3条:
再发送1条:
超出的消息被转发到了死信队列中。
以上就是RabbitMQ死信队列及那些情况消息会被转发到死信队列中。
完毕!!!
给个关注+转发呗谢谢
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80028.html