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

前言

在项目中经常有延迟业务处理的背景,此时可以借助于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,证明我们延迟队列发送消息成功。

<think>嗯,用户想学习消息队列MQ,需要制定一个学习路径和内容。首先,我得确定消息队列的基础知识包括哪些。根据引用[1],MQ是跨进程的通信机制,用于上下游传递消息。所以,应该从基本概念开始,比如消息队列的作用、主要组成部分。然后,消息通道模式,引用[2]提到了队列作为先进先出的数据结构,适合处理消息,可能需要介绍不同的MQ产品,比如RabbitMQ、ActiveMQ等。同时,质量属性如并发支持、性能、错误处理、安全性和持久化这些方面也需要涵盖。 接下来,用户可能需要了解消息队列的核心模式。引用[5]提到了Message Channel和Publisher-Subscriber模式,还有引用[2]详细讨论了发布者-订阅者模式。这部分需要解释这些模式的工作原理和应用场景,可能还需要比较不同模式之间的差异,比如点对点和发布订阅的区别。 然后是具体产品的学习,比如RabbitMQ。引用[3]指出RabbitMQ基于Erlang,有良好的并发处理能力,支持多种客户端API。学习RabbitMQ安装配置、基本操作,比如创建交换机和队列,绑定它们,引用[4]中的命令示例应该有用。此外,高级特性如持久化、集群、事务和确认机制也是重点。 分布式系统中的高级应用部分,引用[5]提到当系统复杂时,需要支持多个队列的部署,可能涉及分布式队列和路由策略。这里需要包括消息路由、负载均衡、死信队列、延迟队列以及与其他系统的集成,比如微服务中的服务解耦。 学习资源方面,官方文档肯定是首要推荐的,比如RabbitMQ和Kafka的文档。书籍的话,《RabbitMQ实战》和《Kafka权威指南》应该不错。在线课程平台可能有相关课程,实验环境可以用Docker搭建,方便练习。 实践项目部分,用户需要实际应用所学知识,比如设计订单处理系统,使用MQ解耦服务,或者日志收集系统,用Kafka处理日志。这些项目能帮助巩固知识,并展示实际应用能力。 进阶方向可能包括源码研究,比如RabbitMQ的Erlang实现,或者参与开源项目。引用[3]提到Erlang的并发优势,可能值得深入学习。另外,云原生时代的MQ应用,如Serverless和K8s集成,也是趋势。 最后,要确保用户按照路径逐步学习,从基础到高级,结合理论与实践,同时提供相关资源和常见问题解答。这样用户才能系统地掌握消息队列MQ的知识,并应用到实际项目中。</think>### 消息队列 MQ 学习路径与内容规划 #### 一、基础概念与核心组件 1. **消息队列的作用与价值** - 理解异步通信、系统解耦、流量削峰、消息持久化等核心功能[^1][^2]。 - 典型应用场景:订单处理、日志收集、分布式事务协调等。 2. **消息队列核心概念** - **消息通道(Message Channel)**:通过队列实现先进先出的消息传递。 - **发布者-订阅者(Publisher-Subscriber)模式**:生产者发布消息到交换机,消费者通过绑定队列接收消息[^4]。 - **交换机(Exchange)与路由键(Routing Key)**:如 `sudo rabbitmqctl bind_queue my_queue my_exchange routing_key` 实现绑定。 3. **主流 MQ 产品对比** - RabbitMQ(高并发、易扩展)[^3]、Kafka(高吞吐、流处理)、RocketMQ(事务消息)、ActiveMQ(传统企业应用)。 --- #### 二、核心技术与实践 1. **消息传递模式** - **点对点(Queue)** vs **发布订阅(Topic)** - 消息确认机制(ACK/NACK)、持久化、TTL(消息存活时间)。 2. **RabbitMQ 深度实践** - **安装与配置**:支持 Windows/Linux 部署,集群配置[^3]。 - **核心组件操作**: ```bash # 创建队列与交换机绑定 sudo rabbitmqctl declare_queue my_queue sudo rabbitmqctl bind_queue my_queue my_exchange routing_key ``` - **高级特性**:镜像队列、死信队列、延迟插件。 3. **消息可靠性与性能优化** - 事务机制 vs 生产者确认(Publisher Confirm)。 - 消费者批量拉取、预取(Prefetch)设置提升吞吐量。 --- #### 三、分布式系统中的高级应用 1. **消息队列与系统架构** - 微服务解耦:通过 MQ 实现服务间异步通信。 - 分布式事务:基于最终一致性的补偿事务(如 Saga 模式)。 2. **高可用与容灾设计** - RabbitMQ 集群部署与镜像队列[^3]。 - Kafka 分区(Partition)与副本(Replica)机制。 3. **典型问题解决方案** - **消息重复消费**:幂等性设计(如唯一业务 ID)。 - **消息堆积**:动态扩容消费者或队列。 --- #### 四、学习资源与工具 1. **官方文档与书籍** - RabbitMQ 官方文档(含教程与 API 指南)。 - 《RabbitMQ实战:高效部署分布式消息队列》《Kafka权威指南》。 2. **动手实验** - 使用 Docker 快速搭建 RabbitMQ/Kafka 环境: ```bash docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management ``` - 通过 `rabbitmqctl` 命令行工具管理队列与交换机。 3. **在线课程与社区** - 极客时间《消息队列高手课》、Coursera 分布式系统专题。 - GitHub 开源项目(如 RabbitMQ 插件开发)。 --- #### 五、实践项目建议 1. **项目 1:订单异步处理系统** - 生产者发送订单消息,消费者处理库存扣减与支付通知,通过 RabbitMQ 实现解耦。 2. **项目 2:日志收集与分析平台** - 使用 Kafka 接收应用日志,通过 Flink 实时分析错误频率。 --- #### 六、进阶方向 1. **源码研究**:分析 RabbitMQ 的 Erlang 实现(高并发设计)。 2. **云原生 MQ**:Serverless 场景下的消息队列(如 AWS SQS、Azure Service Bus)。 3. **性能调优**:结合 JMeter 压测,优化消息吞吐量与延迟。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值