基于插件实现RabbitMQ“延时队列“

1.官网下载

添加链接描述下载rabbitmq_delayed_message_exchange 插件,本文以v3.10.0为例

1.1.上传安装包

powershell 复制代码
scp /Users/hong/资料/rabbitmq_delayed_message_exchange-3.10.0.ez  root@10.211.55.4:/usr/local/software


1.2.将文件移入RabbitMQ的安装目录下的plugins目录

powershell 复制代码
mv rabbitmq_delayed_message_exchange-3.10.0.ez /usr/local/software/rabbitmq_server-3.10.0/plugins


1.3.安装插件

bash 复制代码
rabbitmq-plugins enable rabbitmq_delayed_message_exchange

1.4 重启后验证

bash 复制代码
rabbitmq-server start

2.两种实现方式图解


3.基于插件的延迟队列配置类

java 复制代码
package com.hong.springboot.rabbitmq.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;

import java.util.HashMap;
import java.util.Map;


/**
 * @Description: 延迟队列配置类
 * @Author: hong
 * @Date: 2024-02-25 20:19
 * @Version: 1.0
 **/
@Configuration
public class DelayedQueueConfig {
    public static final String DELAYED_QUEUE_NAME = "delayed.queue";
    public static final String DELAYED_EXCHANGE_NAME = "delayed.exchange";
    public static final String DELAYED_ROUTING_KEY = "delayed.routingKey";

    /**
     * 基于延迟插件声明自定义交换机
     * @return
     */
    @Bean
    public CustomExchange delayedExchange(){
        Map<String,Object> map = new HashMap<>();
        map.put("x-delayed-type","direct");
        /**
         * 声明自定义交换机
         * 第1个参数:交换机名称
         * 第2个参数:交换机类型
         * 第3个参数:是否需要持久化
         * 第4个参数:是否需要自动删除
         * 第5个参数:其他参数
         */
        return new CustomExchange(DELAYED_EXCHANGE_NAME,"x-delayed-message",true,false,map);
    }

    @Bean
    public Queue delayedQueue(){
        return  new Queue(DELAYED_QUEUE_NAME);
    }

    @Bean
    public Binding delayedQueueBindingDelayedExchange(@Qualifier("delayedQueue") Queue delayedQueue,
                                  @Qualifier("delayedExchange") CustomExchange delayedExchange) {
        return BindingBuilder.bind(delayedQueue).to(delayedExchange).with(DELAYED_ROUTING_KEY).noargs();
    }
}

4.生产者发送消息

java 复制代码
    /**
     * 基于延迟插件的发送消息
     * @param message
     * @param delayTime 延迟时间
     */
    @GetMapping("sendDelayMsg/{message}/{delayTime}")
    public void sendMsg(@PathVariable String message, @PathVariable Integer delayTime) {
        rabbitTemplate.convertAndSend(DelayedQueueConfig.DELAYED_EXCHANGE_NAME, DelayedQueueConfig.DELAYED_ROUTING_KEY, message, correlationData -> {
            correlationData.getMessageProperties().setDelay(delayTime);
            return correlationData;
        });
        log.info("当前时间:{},发送一条时长{}毫秒TTL信息给延迟队列delayed.queue:{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , delayTime, message);
    }

5.消费者端代码

java 复制代码
package com.hong.springboot.rabbitmq.consumer;

import com.hong.springboot.rabbitmq.config.DelayedQueueConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Description: 基于延迟插件的延迟消费者
 * @Author: hong
 * @Date: 2024-02-25 21:27
 * @Version: 1.0
 **/
@Slf4j
@Component
public class DelayQueueConsumer {
    @RabbitListener(queues = DelayedQueueConfig.DELAYED_QUEUE_NAME)
    public void receiveDelayMessage(Message message){
        String msg = new String(message.getBody());
        log.info("当前时间:{},收到延迟队列信息{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , msg);
    }
}

http://localhost:8080/ttl/sendDelayMsg/hello rabbitmq 1/20000

http://localhost:8080/ttl/sendDelayMsg/hello rabbitmq 2/2000

基于插件的延迟与基于死信队列的结果恰好相反更符合预期,因此在实际项目中通常采用延迟插件方式来实现rabbitMQ的延迟队列

相关推荐
程序员小潘2 小时前
Dubbo分布式日志跟踪实现
分布式·dubbo
CodingBrother4 小时前
Kafka简单实践
分布式·kafka
不太灵光的程序员5 小时前
【HBase分布式数据库】第七章 数据的导入导出 importtsv导入数据
数据库·分布式·hbase
Acrel_WPP6 小时前
分布式光伏智慧平台建设现场 系统集成商如何盈利
分布式
大山同学6 小时前
DPGO:异步和并行分布式位姿图优化 2020 RA-L best paper
人工智能·分布式·语言模型·去中心化·slam·感知定位
Lyqfor7 小时前
云原生学习
java·分布式·学习·阿里云·云原生
流雨声8 小时前
2024-09-01 - 分布式集群网关 - LoadBalancer - 阿里篇 - 流雨声
分布式
floret*8 小时前
用pyspark把kafka主题数据经过etl导入另一个主题中的有关报错
分布式·kafka·etl
william8239 小时前
Information Server 中共享开源服务中 kafka 的__consumer_offsets目录过大清理
分布式·kafka·开源
P.H. Infinity9 小时前
【RabbitMQ】10-抽取MQ工具
数据库·分布式·rabbitmq