RabbitMQ系列(22)--RabbitMQ优先级队列

前言:在购物系统中有一个订单催付的场景,如果客户在购物系统下单后在设定的时间内未付款那么就会给客户推送一条短信提醒,这是一个比较简单的功能,但是,商家对我们来说,肯定是要区分大客户和小客户的,比如像苹果、华为、小米这样的大商家一年能给我们创造很大的利润,在业务高峰时期,订单堆积,来不及处理,而为了创造最大的利润,他们的订单必须得到优先处理,而曾经的后端系统是使用redis来存放短信提醒的,并通过定时轮询实现短信发送,但大家都知道redis只能用List做一个简简单单的消息队列,并不能实现一个优先级的场景,所以后来需要采用RabbitMQ对系统进行改造和优化,如果发现是大客户的订单给一个相对比较高的优先级,否则就是默认优先级,而实现优先级就用到了RabbitMQ的优先级队列。

1、在config包里新建一个名为PriorityQueueConfig的类用于编写配置交换机、队列、routingkey的代码

代码如下:

package com.ken.springbootrqbbitmq.config;import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class PriorityQueueConfig {//交换机public static final String EXCHANGE_NAME = "priority_exchange";//队列public static final String QUEUE_NAME = "priority_queue";//routingkeypublic static final String ROUTING_KEY = "priority";//声明交换机@Bean("directExchange")public DirectExchange priorityExchange() {return new DirectExchange(EXCHANGE_NAME);}//声明队列@Bean("priorityQueue")public Queue priorityQueue() {//官方允许范围为0-255,这里设置10,即允许优先级的范围为0-10return QueueBuilder.durable().withArgument("x-max-priority",10).build();}//绑定交换机和队列@Beanpublic Binding warningQueueBindingBackupExchange(@Qualifier("priorityQueue") Queue priorityQueue,@Qualifier("directExchange") DirectExchange directExchange) {return BindingBuilder.bind(priorityQueue).to(directExchange).with(ROUTING_KEY);}}

2、在controller包里新建一个名为SendPriorityMsgController的类用于编写充当生产者发送消息的代码

代码如下:

package com.ken.springbootrqbbitmq.controller;import com.ken.springbootrqbbitmq.config.PriorityQueueConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
@RequestMapping("/priority")
public class SendPriorityMsgController {@Autowired(required = false)private RabbitTemplate rabbitTemplate;//发消息@GetMapping("/sendPriorityMessage/{message}")public void sendMessage(@PathVariable String message) {for (int i = 1; i <= 10; i++) {String msg = message + i;if(i == 5) {//给第5条消息设置优先级为5(数字越大优先级越高)rabbitTemplate.convertAndSend(PriorityQueueConfig.EXCHANGE_NAME,PriorityQueueConfig.ROUTING_KEY,msg,correlationData -> {correlationData.getMessageProperties().setPriority(5);return correlationData;});}else {rabbitTemplate.convertAndSend(PriorityQueueConfig.EXCHANGE_NAME,PriorityQueueConfig.ROUTING_KEY,msg);}log.info("发送消息内容:{}",msg);}}}

3、在consumer包里新建一个名为PriorityQueueConsumer的类用于编写充当消费者消费消息的代码

代码如下:

package com.ken.springbootrqbbitmq.consumer;import com.ken.springbootrqbbitmq.config.PriorityQueueConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class PriorityQueueConsumer {@RabbitListener(queues = PriorityQueueConfig.QUEUE_NAME)public void receivePriorityMsg(Message message) {String msg = new String(message.getBody());log.info("接收到的消息为:{}",msg);}}

4、先注释消费者的代码,然后启动项目, 在浏览器地址栏调用发送消息的接口

http://localhost:8080/priority/sendPriorityMessage/我是消息

生产者发送消息后,没有消费者消费消息,消息就会堆积在队列中,可以用于模拟在业务高峰时期,订单堆积,来不及处理的场景。

效果图:

5、去掉消费者代码里的注释,然后重新启动项目,可以得见消息被消费者消费了,且第5条消息由于优先级是5,在所有的消息里优先级最高,被优先消费了,这证明我们的优先队列成功实现了

 效果图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/14161.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计合并排序算法实现对N个整数排序。

1.题目 设计合并排序算法实现对N个整数排序 2.设计思路 先将无序序列利用分治法划分为子序列&#xff0c;直至每个子序列只有一个元素&#xff0c;然后再对有序子序列逐步进行合并排序。合并方法是循环的将两个有序子序列当前的首元素进行比较&#xff0c;较小的元素取出&…

Node中的模块引擎EJS模块渲染

1.导入 const ejsrequire("ejs") 2.声明数组 const group["张三","李四","王二","麻子"] 3.EJS实现 let resultejs.render(<ul> <% group.forEach(item>{ %> <li><%item%></li> <% }) …

Kotlin单例模式的一种懒汉模式写法

Kotlin单例模式的一种懒汉模式写法 class MyHelpler {companion object {private val singleHelpler by lazy(mode LazyThreadSafetyMode.SYNCHRONIZED) { MyHelpler() }fun instance() singleHelpler}fun sayHi() {println("fly")} }fun main(args: Array<Stri…

BOM操作

JavaScript组成 BOM 浏览器对象模型 window对象 是一个全局对象&#xff0c;也就是JavaScript中的顶级对象 像document&#xff0c;alert() console.log() 都是window对象的属性&#xff0c; 基本的BOM的属性和方法都属于window对象 通过var定义在全局作用域中的变量&#x…

从开机开始

1. 开机之后&#xff0c;计算机干了什么&#xff1f; 加载BIOS&#xff1a;计算机通电后&#xff0c;基本输入/输出系统&#xff08;BIOS&#xff09;会首先运行。BIOS是一个固件程序&#xff0c;它位于计算机主板上的芯片中&#xff0c;并负责初始化硬件设备、检测和解决问题…

106、基于STM32单片机万年历闹钟温度LCD1602系统设计(程序+原理图+PCB源文件+参考论文+开题报告+硬件设计资料+元器件清单等)

摘 要 本文介绍了基于STM32单片机的多功能电子万年历的硬件结构和软硬件设计方法。本设计由数据显示模块、温度采集模块、时间处理模块和调整设置模块四个模块组成。系统以STM32单片机为控制器&#xff0c;以串行时钟日历芯片DS1302记录日历和时间&#xff0c;它可以对年、月、…

Redis缓存同步1-策略介绍

缓存数据同步策略示意图 在大多数情况下&#xff0c;我们通过浏览器查询到的数据都是缓存数据&#xff0c;如果缓存数据与数据库的数据存在较大差异的话&#xff0c;可能会产生比较严重的后果的。所以&#xff0c;我们应该也必须保证数据库数据、缓存数据的一致性&#xff0c;…

Django_MVT(二)

目录 一、MVT简介 二、M-模型类 1. 定义模型类 2. 迁移 2.1 生成迁移文件命令如下&#xff1a; 2.2 执行迁移命令如下&#xff1a; 3. 数据基础操作 三、V-视图 1.定义视图 2.配置URLconf 访问服务器 四、T-模板 创建模板文件 定义模板 视图调用模板 视图调用模…

Ubuntu 的移动梦醒了

老实讲&#xff0c;移动版 Ubuntu 在手机、平板上的发展自始至终可能都没有达到过 Canonical 的期望&#xff0c;既然如此&#xff0c;不再勉为其难地坚持下去&#xff0c;或许才是更加明智的做法。 时至今日&#xff0c;官方显然也意识到了这一点&#xff0c;在早些时候发布的…

Linux安装配置Oracle+plsql安装配置(超详细)

注意&#xff1a;本文有大量的界面截图&#xff0c;如观看效果不佳可前往文字版&#xff1a; Linux安装配置Oracleplsql安装配置&#xff08;详细&#xff09;_超爱慢的博客-CSDN博客 目录 1 安装虚拟机系统 1.1 安装虚拟机 2.配置虚拟机 2.1 设置机器名 2.2 修改域名映射…

【编译原理】词法分析程序设计(C语言)

目录 一、实验内容二、实验原理三、结果分析四、源代码一、实验内容 给定下表所示的一个简单语言的词法规则描述完成以下任务: (1)画出识别该语言词法规则的状态转换图; (2)依据状态转换图,设计并编制词法分析程序,实现从输入源程序中,识别出各类单词,即关键字、标识…

keepalived

文章目录 一、suse系统安装keepalived1.1、准备环境1.2、修改主机名1.3、关闭防火墙1.4、配置网络1.5、配置 yum 源1.6、安装 mysql1.7、安装 keepalived报错信息&#xff1a;使用 wget 下载keepalived 报错解决 使用 wget 下载 keepalived的报错 一、suse系统安装keepalived …