RabbitMq实现延迟队列功能

1、rabbitmq服务端打开延迟插件 (超过 4294967295毫秒 ≈ 1193 小时 ≈ 49.7 天 这个时间会立即触发)

注意:只有RabbitMQ 3.6.x以上才支持

在下载好之后,解压得到.ez结尾的插件包,将其复制到RabbitMQ安装目录下的plugins文件夹。

然后通过命令行启用该插件:

|-------------------------------------------------------------------|
| rabbitmq-plugins enable rabbitmq_delayed_message_exchange |

该插件在通过上述命令启用后就可以直接使用,不需要重启。

2、添加依赖

复制代码
<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-amqp</artifactId>
 </dependency>

3、配置交换机和队列

复制代码
@Configuration
public class DelayedConfig {

    public static String EXCHANGE_NAME = "delayed_exchange";
    public static String QUEUE_NAME = "delayed_queue";
    public static String KEY_NAME = "delayed_key";

    /**
     * 基于插件实现的交换机,必须是CustomExchange类型,标识这是一个延时类型的交换机
     */
    @Bean()
    public CustomExchange delayedExchange(){
        Map<String,Object> params = new HashMap<>();
        params.put("x-delayed-type","direct");
        //参数1:交换机名字,参数2:交换机的类型,参数3:是否持久化,参数4:是否自动删除队列,参数5:交换机的额外参数设置
        return new CustomExchange(EXCHANGE_NAME,"x-delayed-message",true,false,params);
    }

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

    @Bean
    public Binding delayedBinding(){
        return BindingBuilder.bind(delayedQueue()).to(delayedExchange()).with(KEY_NAME).noargs();
    }

}

4、发送和接收消息

复制代码
@GetMapping("/t5")
    public void t5(){
        Date date = new Date();
        System.out.println("发送时间:" + date.toString());
        //发送消息
        rabbitTemplate.convertAndSend(DelayedConfig.EXCHANGE_NAME,DelayedConfig.KEY_NAME,"1延迟消息wxm",
            msg->{msg.getMessageProperties().setHeader(MessageProperties.X_DELAY, 15552000000L);
                  msg.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                return msg;});
        //发送消息
        rabbitTemplate.convertAndSend(DelayedConfig.EXCHANGE_NAME,DelayedConfig.KEY_NAME,"延迟消息wxm",
            msg->{msg.getMessageProperties().setDelay(10000);
                msg.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                return msg;});
        log.info("发送成功");
    }
    @RabbitHandler
    @RabbitListener(queues = "delayed_queue")
    public void getDelayed(Message message, Channel channel) throws Exception{
        Date date = new Date();
        String rightNow = date.toString();
        String msg = new String(message.getBody());
        // 手动应答
        System.out.println(message.getMessageProperties().getDeliveryTag());
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
        System.out.println("接受成功:"+msg+rightNow);
    }
相关推荐
NE_STOP5 小时前
MyBatis-配置文件解读及MyBatis为何不用编写Mapper接口的实现类
java
后端AI实验室10 小时前
用AI写代码,我差点把漏洞发上线:血泪总结的10个教训
java·ai
程序员清风11 小时前
小红书二面:Spring Boot的单例模式是如何实现的?
java·后端·面试
belhomme11 小时前
(面试题)Redis实现 IP 维度滑动窗口限流实践
java·面试
Be_Better12 小时前
学会与虚拟机对话---ASM
java
开源之眼14 小时前
《github star 加星 Taimili.com 艾米莉 》为什么Java里面,Service 层不直接返回 Result 对象?
java·后端·github
Maori31615 小时前
放弃 SDKMAN!在 Garuda Linux + Fish 环境下的优雅 Java 管理指南
java
用户9083246027315 小时前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
小王和八蛋15 小时前
DecimalFormat 与 BigDecimal
java·后端
beata16 小时前
Java基础-16:Java内置锁的四种状态及其转换机制详解-从无锁到重量级锁的进化与优化指南
java·后端