Docker版RabbitMQ安装延迟队列插件及延迟队列项目应用实战

news2024/11/27 7:36:50

前言

在项目中经常有延迟业务处理的背景,此时可以借助于Rabbitmq的延迟队列进行实现,但Rabbitmq本身并不支持延迟队列,但可以通过安装插件的方式实现延迟队列

环境准备

  1. 首先确认目前项目使用的Rabbitmq的版本,这里博主的版本是3.9.15的。
    在这里插入图片描述
  2. 访问 Rabbitmq的github网址,检索 delay 找到插件rabbitmq-delayed-message-exchange ,如下图所示:
    在这里插入图片描述
  3. 找到延迟队列插件相应的版本并进行下载。
    在这里插入图片描述
    博主的Rabbitmq是3.9版本的,所以这里选择3.9版本即可如下图所示:
    在这里插入图片描述
    下载 rabbitmq_delayed_message_exchange-3.9.0.ez
    在这里插入图片描述

安装延迟队列

上面我们已经成功下载了延迟队列插件,接下来我们需要将此插件上传到Linux系统服务器上,然后再将插件拷贝到Rabbitmq的容器中。

  1. 查看Rabbitmq容器进程
    在这里插入图片描述
  2. 将Rabbitmq延迟队列插件拷贝到容器中
# c94f1e7dbfc0 代表容器Id,通过上面1的步骤即可查看
docker cp rabbitmq_delayed_message_exchange-3.9.0.ez c94f1e7dbfc0:/opt/rabbitmq/plugins
  1. 进入容器并安装延迟队列插件
docker exec -it c94f1e7dbfc0 /bin/bash

在这里插入图片描述
查看 /opt/rabbitmq/plugins,是否已经有了延迟队列插件。如下图所示:
在这里插入图片描述
安装插件

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

在这里插入图片描述
4. 安装消息管理插件

 rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management

在这里插入图片描述
4. 查看已经安装的Rabbitmq插件
在这里插入图片描述
5. 控制台查看验证延迟队列类型如下图:
加粗样式

延迟队列实战

SpringBoot项目中引入Rabbitmq的依赖项

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

新增一个交换机、一个队列然后绑定队列与交换机如下图所示:

@Configuration
public class RabbitmqConfig {
    @Bean(name = "updateAmount")
    public TopicExchange lazyExchange() {
        Map<String, Object> pros = new HashMap<>();
        //设置交换机支持延迟消息推送
        pros.put("x-delayed-type", "direct");
        TopicExchange exchange = new TopicExchange("updateAmount", true, false,pros);
        // 这一行是重点,指定交换机类型
        exchange.setDelayed(true);
        return exchange;
    }

    @Bean
    public Queue lazyQueue(){
        return new Queue("LAZY_QUEUE", true);
    }

    @Bean
    public Binding lazyBinding(){
        return BindingBuilder.bind(lazyQueue()).to(lazyExchange()).with("");
    }
}

新增发送延迟队列的工具类代码逻辑:

public class RabbitmqUtils {


    /**
     * 发送延迟消息
     * @param rabbitTemplate rabbitTemplate
     * @param millisecond 延迟毫秒
     * @param messageContent 发送字符串
     * @param busiId 业务主键id
     */
    public static void sendDelayMessage(RabbitTemplate rabbitTemplate, Integer millisecond, Object messageContent, Long busiId) {
        CorrelationData correlationData = new CorrelationData(busiId.toString() + System.currentTimeMillis());
        rabbitTemplate.convertAndSend("updateAmount", "", messageContent,
                message -> {
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    message.getMessageProperties().setDelay(millisecond);
                    return message;
                }, correlationData);
    }
}

新增一个监听器代码消费延迟队列的消息:

@Component
@Slf4j
@RequiredArgsConstructor
@RabbitListener(queues = "LAZY_QUEUE")
public class RabbitmqListener {

    private final ObjectMapper objectMapper;


    @RabbitHandler
    public void onCustomBookingMessage(@Payload String message, Channel channel, @Headers Map<String, Object> headers) {
        Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        try {
            Map map = objectMapper.readValue(message, Map.class);
            log.info("接收消息成功,消息内容:"+map);
            ack(channel,deliveryTag,"");
        } catch (JsonProcessingException e) {
            nack(channel,deliveryTag,"");
        }
    }


    /**
     * 确认消息成功
     */
    public void ack(Channel channel, long deliveryTag, String info) {
        try {
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
            log.error(info + ":消息应答出错", e);
        }
    }

    /**
     * 确认消息失败
     */
    public void nack(Channel channel, long deliveryTag, String info) {
        try {
            channel.basicNack(deliveryTag, false, true);
        } catch (IOException e) {
            log.error(info + ":消息拒绝出错", e);
        }
    }
}

新增一个生产者发送消息的代码:

@RequestMapping("/rabbit")
@RequiredArgsConstructor
@RestController
@Slf4j
public class RabbitmqController {
    private final RabbitTemplate rabbitTemplate;

    private final ObjectMapper objectMapper;


    @GetMapping("/sendMessage")
    public void sendDeLayMessage() throws JsonProcessingException {
        Map<String,Object> map = new HashMap<>();
        map.put("username","zhangsan");
        map.put("tranferMoney",new BigDecimal("1200.23"));
        map.put("time", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        // 发送消息
        RabbitmqUtils.sendDelayMessage(rabbitTemplate,7000,objectMapper.writeValueAsString(map),System.currentTimeMillis());
        log.info("发送延迟队列消息成功:消息内容:"+map);
    };
}

在浏览器访问:http://127.0.0.1:8080/rabbit/sendMessage 后可以看到控制台输出如下日志:
在这里插入图片描述
因为我们设定延迟时间为7s,可以清晰看到日志打印的时间刚好相聚了7s,证明我们延迟队列发送消息成功。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32系列(HAL库)——使用ESP8266-01S物联网模块连接Onenet云平台上报DHT11温湿度

前言 本篇主要讲解如何使用ESP8266-01S物联网模块连接Onenet云平台&#xff0c;并上报DHT11模块的温湿度数据。本文单片机主控采用STM32F405RGT6&#xff0c;使用其他主控的话基本要求有2个串口&#xff0c;一个串口用于调试使用&#xff0c;另一个用于ESP模块通讯。 一、前…

SOLIDWORKS 2023工程图和出详图新功能 创建更智能化 更高精度的工程详图

工程图是传达您设计意图的重要文档&#xff0c;您设计的产品越复杂&#xff0c;越需要详细注释说明。SOLIDWORKS 2023增强的工程图和出详图功能将帮助您创建更智能化、更高精度的工程详图&#xff0c;并且扩展新功能使您的设计工作延伸到更多的业务领域。您现在可以从更高层级的…

C 程序设计教程(15)—— 选择结构程序设计练习题

C 程序设计教程&#xff08;15&#xff09;—— 选择结构程序设计练习题 该专栏主要介绍 C 语言的基本语法&#xff0c;作为《程序设计语言》课程的课件与参考资料&#xff0c;用于《程序设计语言》课程的教学&#xff0c;供入门级用户阅读。 目录C 程序设计教程&#xff08;1…

20230110配置ubuntu18.04为开机自动登录

20230110配置ubuntu18.04为开机自动登录 百度搜索&#xff1a;ubuntu 18.04 开机自动登录 https://blog.csdn.net/yang1994/article/details/124446319 通过配置文件启用/禁用Ubuntu 18.04自动登录 超级用户可以通过编辑custom.conf配置文件的方式&#xff0c;来为自己或任何其…

计算机如何存储浮点数和定点数?

1 浮点数的不精确性 能不能用二进制表示所有实数&#xff0c;然后在二进制下计算它的加减乘除呢&#xff1f; 打开Chrome Console&#xff0c;输入0.3 0.6&#xff1a; 简单加法在js算出结果居然不是准确的0.9&#xff0c;而是0.8999999999999999&#xff0c;why&#xff1…

火山语音丨AI创作惊艳四方 诸多挑战仍在路上

2022年8月&#xff0c;一幅名为《太空歌剧院》的数字画作获得冠军同时引发了巨大争议&#xff0c;AIGC&#xff08;AI产生内容&#xff1a;AI-Generated Content&#xff09;出圈的事件便频频出现在大众视野。同年11月30日OpenAI发布的聊天机器人模型ChatGPT免费开放&#xff0…

从0到1完成一个Vue后台管理项目(二十、地图涟漪、线图)

往期 从0到1完成一个Vue后台管理项目&#xff08;一、创建项目&#xff09; 从0到1完成一个Vue后台管理项目&#xff08;二、使用element-ui&#xff09; 从0到1完成一个Vue后台管理项目&#xff08;三、使用SCSS/LESS&#xff0c;安装图标库&#xff09; 从0到1完成一个Vu…

缓存穿透、布隆过滤器、布谷鸟过滤器

1.概述 缓存穿透&#xff1a; 当查询的数据在缓存&#xff08;redis&#xff09;中没有时&#xff0c;一般业务上就会去查询数据存储&#xff08;数据库&#xff09;&#xff0c;这种情况称为缓存穿透。穿透的数量太大会造成数据存储撑不住&#xff08;数据库&#xff09;而宕…

基于控制器软件需求事项进行单元测试和单元测试规范

基于需求事项的单元测试是什么&#xff1f; ​ 大多数汽车行业都遵循 ISO 26262 中定义的标准&#xff0c;这是 ISO 制定的汽车功能安全国际标准。 根据 ISO 26262 标准软件单元测试 (ISO 26262-6-9)&#xff0c;单元验证是验证要验证的单元&#xff08;功能或功能&#xff09…

智能优化算法应用:基于蜣螂优化算法的工程优化案例

智能优化算法应用&#xff1a;基于蜣螂算法的工程优化案例 文章目录智能优化算法应用&#xff1a;基于蜣螂算法的工程优化案例1.蜣螂算法2.压力容器设计问题3.三杆桁架设计问题4.拉压弹簧设计问题5.Matlab代码6.Python代码摘要&#xff1a;本文介绍利用蜣螂搜索算法&#xff0c…

MyBatis框架知识点总结

一、引言1.1 什么是框架&#xff1f;框架&#xff1a;框架使用你的&#xff0c;而不是你在使用框架的。框架让我们提供什么信息&#xff0c;配置信息&#xff0c;数据库连接用户名密码等&#xff0c;你必须提供&#xff0c;还得按照框架要要求的方式提供&#xff0c;否则你就别…

《图机器学习》-Node Embeddings

Node Embeddings一、Graph Representation Learning二、Node Embeddings&#xff1a;Encoder and Decoder三、Random Walk Approaches for Node Embeddings一、Graph Representation Learning 在传统的图机器学习中&#xff0c;依赖于手工特征工程(即由特征工程师去设计节点、…

每日一题:Leetcode54. 螺旋矩阵

文章目录 系列&#xff1a;数组专练 语言&#xff1a;java & go 题目来源&#xff1a;Leetcode54. 螺旋矩阵 难度&#xff1a;中等 考点&#xff1a;边界问题处理 思路和参考答案文章目录题目描述思路java参考代码go参考代码&#xff1a;题目描述 给你一个 m 行 n 列的矩…

力扣sql基础篇(三)

力扣sql基础篇(三) 1 查询结果的质量和占比 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 把该列置为null的话,它就不会统计了 SELECT query_name,ROUND(sum(rating/position)/count(*),2) quality, ROUND(count(IF(rating<3,rating,null))/c…

【数据结构】—— Java实现双向链表

Java实现双向链表一、链表的概念及结构二、头指针与头结点的异同三、代码实现一、链表的概念及结构 我们在单链表中&#xff0c;有了next指针。这就使得我们查找下一个结点的时间复杂度为O(1)。可是我们要查找的是上一个结点的话&#xff0c;那最坏的时间复杂度就是O(n)了&…

用图记忆C语言中的运算符优先级

运算符优先级以及结合方向的统计表&#xff0c;网上到处可见。本文画了一张图&#xff0c;以便记忆&#xff01; 1. 总体来说优先级 初级运算 > 单目运算 > 双目运算 > 三目运算 > 赋值运算 > 逗号运算 2. 双目细分 算术运算 > 位移运算 > 关系运算 &g…

今年十八,基础过关

目录 前言 第一关&#xff1a;KEY在哪里 再加密一次你就得到key啦~ 猜猜这是经过了多少次加密&#xff1f; 据说MD5加密很安全&#xff0c;真的是么&#xff1f; 种族歧视 HAHA浏览器 key究竟在哪里呢&#xff1f; key又找不到了 冒充登陆用户​编辑 比较数字大小 就不让你…

Linux应用编程---14.UDP服务器、客户端编程

Linux应用编程—14.UDP服务器、客户端编程 ​ 之前有介绍过UDP是一种无连接、尽最大努力交付、面向报文的协议。应用层交给UDP多长的报文&#xff0c;UDP就照样发送。Linux下UDP属于数据报socket。数据报socket流程图如图1所示&#xff1a; 图1 数据报socket流程图 ​ 新引入的…

FourIE:一种最新联合事件抽取SOTA论文解读

Cross-Task Instance Representation Interactions and Label Dependencies for Joint Information Extraction with Graph Convolutional Networks 论文&#xff1a;Cross-Task Instance Representation Interactions and Label Dependencies for Joint Information Extractio…

Vue2的前端路由(vue-router)

一、路由 路由 (英文&#xff1a;router)就是页面地址与组件之间的对应关系 二、路由方式 服务器端路由、前端路由 三、前端路由 前端路由&#xff1a;地址和组件之间的对应关系&#xff0c;即由前端来维护一组路由规则&#xff08;地址和组件之间的对应关系&#xff09;&…