Springboot整合RabbitMQ死信队列详解

95 篇文章 3 订阅
60 篇文章 2 订阅

环境:Spring Boot2.3.10 + RabbitMQ 3.8.12 + Erlang 23.2.5


死信队列介绍

来自队列的消息可以是“死信”消息;也就是说,当发生以下任何事件时,可以重新发布到
exchange:

  1. 当消费者使用basic.reject or basic.nack 方法并且requeue 参数设置为false时。
  2. 消息设置了TTL参数(建立队列时设置了x-message-ttl参数),消息过期;或消息被丢弃,因为其队列超过了长度限制。

注意:队列的过期不会导致其中的消息死信(建立队列时设置了x-expires参数)。

死信交换机也是正常的交换机,可以是任何类型的交换机。

在创建队列的时候可以指定x-dead-letter-exchange,x-dead-letter-routing-key(可选)参数指定当发生上述2个情形时就行重写转发到死信交换机上。

准备环境

  • 新建正常业务所需的交换机及队列

建立business-exchange类型为topic的交换机

Springboot整合RabbitMQ死信队列详解

 

建立dead-exchange类型为fanout类型的交换机;死信交换机

Springboot整合RabbitMQ死信队列详解

 

建立business-queue队列

Springboot整合RabbitMQ死信队列详解

 

这里设置了x-dead-letter-exchange参数,值为上面建立的死信交换机。这里并没有设置x-dead-letter-routing-key参数,因为我们的死信交换机类型为fanout,该类型与routing-key无关。

相应的交换机与队列进行绑定。

Springboot整合RabbitMQ死信队列详解

 

Springboot整合RabbitMQ死信队列详解

 

测试

方式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”时拒绝消息。

发送正常消息:

Springboot整合RabbitMQ死信队列详解

 

Springboot整合RabbitMQ死信队列详解

 

 

发送拒绝消息:

Springboot整合RabbitMQ死信队列详解

 

Springboot整合RabbitMQ死信队列详解

 

查看消息队列

Springboot整合RabbitMQ死信队列详解

 

消息被转发到了死信队列。

方式2:设置消息的TTL参数,设置过期时间。

重新建立business-queue队列。

Springboot整合RabbitMQ死信队列详解

 

x-message-ttl:消息过期时间,单位为毫秒。这里设置10秒后过期。

绑定到交换机,如下图

Springboot整合RabbitMQ死信队列详解

 

把接收消息的监听器注释了,我们这里不进行消息的消费。等到消息过期后消息是否会被转发到死信队列中。

发送消息前查看队列情况

Springboot整合RabbitMQ死信队列详解

 

发送消息

Springboot整合RabbitMQ死信队列详解

 

10s后:

Springboot整合RabbitMQ死信队列详解

 

消息被转发到了死信队列,我们可以查看dead-queue队列中的消息

Springboot整合RabbitMQ死信队列详解

 

方式3:设置消息队列消息数的最大个数。

删除bussiness-queue队列,重新建立

Springboot整合RabbitMQ死信队列详解

 

设置x-max-length值为3,最大只能保存3条消息,超过的被转发到死信队列。

再次与business-exchange进行绑定

Springboot整合RabbitMQ死信队列详解

 

先连续发送3条消息:

发送前消息队列消息情况:

Springboot整合RabbitMQ死信队列详解

 

发送3条:

Springboot整合RabbitMQ死信队列详解

 

再发送1条:

Springboot整合RabbitMQ死信队列详解

 

超出的消息被转发到了死信队列中。

以上就是RabbitMQ死信队列及那些情况消息会被转发到死信队列中。

完毕!!!

给个关注+转发呗谢谢

Springboot整合RabbitMQ死信队列详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值