Springboot整合RabbitMQ延迟队列&优先级队列详解

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

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


延迟队列

延迟队列:简单说就是发送出去的消息经过给定的时间后,消费者才能看见消息(消费消息)。

实现其实就是我们上一篇讲的《Springboot整合RabbitMQ死信队列详解》通过死信队列来实现。

这里简单说下步骤:

  1. 创建一个队列,如:bs-queue, 设置死信交换机(死信交换机路由key(这是可选的))及队列,如:dead-exchange; 消息的消费端监听该dead-queue队列。设置消息有效期参数x-message-ttl参数(值为自己需要延迟的时间,单位:毫秒)。
  2. 发送消息发送到bs-queue上。由于消息消费端监听的是死信队列,所以只需要等待指定的时间后消息会自动被转发到死信队列上(dead-queue)。
  3. 消息的消费端监听dead-queu队列即可。

具体的使用细节大家参考《Springboot整合RabbitMQ死信队列详解》这篇文章。

优先级队列

优先级队列是在RabbitMQ3.5.0之后的版本才支持的。

具有高优先级的队列具有高的优先权,优先级高的消息具备有限被消费的特权。

队列的优先级通过x-max-priority参数设置。

建立一个priority-exchange交换机,类型:direct。

Springboot整合RabbitMQ延迟队列&优先级队列详解

 

建立一个priority-queue队列,并与priority-exchange绑定。

Springboot整合RabbitMQ延迟队列&优先级队列详解

 

设置x-max-priority参数的值为100,表示最大优先级为100。

Springboot整合RabbitMQ延迟队列&优先级队列详解

 

注意:x-max-priority参数的值应该介于1到255。建议使用1到10之间的队列。如果设置的优先级更大将使用更多的Erlang进程消耗更多的CPU资源。运行时调度也会受到影响。

接下来演示优先级队列

我们先只发送消息,然后再把消息的消费功能打开。

发送消息接口:

@GetMapping("/sendPriority")
public Object sendPriority(String msg, Integer priority) {
  ms.sendPriorityQueue(msg, priority) ;
  return "success" ;
}
public void sendPriorityQueue(String msg, Integer priority) {
  logger.info("准备发送消息:{}", msg);
  Message message = MessageBuilder.withBody(msg.getBytes()).setPriority(priority).build() ;
  rabbitTemplate.convertAndSend("priority-exchange", "pe.msg", message) ;
}

发送4条消息:

// 第一条消息
msg=第一条消息&priority=2 
// 第二条消息
msg=第二条消息&priority=10
// 第三条消息
msg=第三条消息&priority=1
// 第四条消息
msg=第四条消息&priority=7

查看消息队列:

Springboot整合RabbitMQ延迟队列&优先级队列详解

 

消息消费端:

@RabbitListener(queues = { "priority-queue" })
@RabbitHandler
public void listenerPriority(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 {
    System.out.println("接受到消息来自交换机: 【" + mps.getReceivedExchange() + "】, 队列:【" + mps.getConsumerQueue()+ "】:\n内容: " + content);
    channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
  } catch (Exception e) {
    e.printStackTrace();
    try {
      channel.basicReject(mps.getDeliveryTag(), false);
    } catch (IOException e1) {
      e1.printStackTrace() ;
    }
  }
}

启动服务

Springboot整合RabbitMQ延迟队列&优先级队列详解

 

根据打印出的结果,正好是我们设置优先级的顺序输出。

上面设置的消息优先级都是在指定的范围<100,如果消息的优先级超过这个值会怎么样呢?

发送8条消息:

// 第一条消息
msg=第一条消息&priority=2 
// 第二条消息
msg=第二条消息&priority=10
// 第三条消息
msg=第三条消息&priority=1
// 第四条消息
msg=第四条消息&priority=7
// 第五条消息
msg=第五条消息&priority=101

消费消息:

Springboot整合RabbitMQ延迟队列&优先级队列详解

 

同样是按照顺序输出的。

注意:官方文档有这么一段原文、

Messages without a priority property are treated as if their priority were 0. Messages with a priority which is higher than the queue's maximum are treated as if they were published with the maximum priority.

大致意思是:没有priority属性的消息被视为优先级为0。优先级高于队列最大优先级的消息将被视为以最大优先级发布的消息。

注意:我在做测试的时候,设置了很多超过100的,还有超过255的,结果发现是乱序的。

完毕!!!

给个关注+转发呗谢谢

Springboot整合RabbitMQ延迟队列&优先级队列详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值