RabbitMQ学习笔记:RabbitMQ延迟队列(DLX、TTL及rabbitmq_delayed_message_exchange插件)

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

延迟队列存储的对象是对应的延迟消息,所谓的延迟消息是指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。

延迟消息使用的场景有很多,比如:

  1. 在订单系统中,一个用户下单之后通常有30分钟的时间进行支付,如果30分钟之内没有支付成功,那么这个订单将进行异常处理,这时候就可以使用延迟队列来处理这些订单了。
  2. 用户希望通过手机远程遥控家里的智能设备在指定的时间进行工作,这时候就可以将用户指令发送到延迟队列,当指令设定的时间到了再将指令推送到只能设备。

在AMQP协议中,或RabbitMQ本身没有直接支持延迟队列的功能,但是可以通过TTL和DLX模拟出延迟队列的功能;也可以通过rabbitmq_delayed_message_exchange插件来实现。

DLX和TTL模拟延迟队列
  • 消息变成死信一般由以下几种情况

    1. 消息被拒绝(Basic.Reject/Basic.Nack),并且设置requeue参数为false;
    2. 消息过期
    3. 队列达到最大长度
  • DLX

DLX是一个正常的交换器,和一般的交换器没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性。当这个队列中存在死信时,RabbitMQ就会自动地将这个消息重新发布到设置的DLX上去,进而被路由到另一个队列,即死信队列。可以监听这个队列中的消息进行相应的处理,这个特性与将消息的TTL设置为0配合使用可以弥补immediate参数的功能。

  • 声明队列、交换器、绑定路由并在容器启动时自动创建,通过在队列的参数上设置x-dead-letter-exchange参数添加死信交换器,设置x-dead-letter-routing-key参数添加死信路由
    package com.yaomy.control.rabbitmq.amqp.ttl.config;
    
    import com.google.common.collect.Maps;
    import org.springframework.amqp.core.*;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.Map;
    
    /**
     * @Description: RabbitMQ生产者交换器、绑定、队列声明
     * @Version: 1.0
     */
    @SuppressWarnings("all")
    @Configuration
    public class RabbitConfig {
        public static final String TTL_TOPIC_EXCHANGE = "ttl.topic.exchange";
        public static final String TTL_TOPIC_QUEUE = "ttl_topic_queue";
        public static final String TTL__TOPIC_ROUTING_KEY = "*.topic.*";
        public static final String TTL_DELAY_EXCHANGE = "ttl.dlx.exchange";
        public static final String TTL_DELAY_ROUTING_KEY = "ttl.dlrk.routingkey";
        public static final String TTL_DELAY_QUEUE = "ttl_dlk_queue";
        /**
         * 声明队列
         */
        @Bean
        public Queue topicQueue(){
            Map<String, Object> args = Maps.newHashMap();
            /**
             * 设置消息发送到队列之后多久被丢弃,单位:毫秒
             */
            args.put("x-message-ttl", 10000);
            /**
             * 消息变成死信一般由以下几种情况引起:
             * 1.消息被拒绝,并且设置requeue参数为false
             * 2.消息过期
             * 3.队列达到最大长度
             * x-dead-letter-exchange参数是指消息编程死信之后重新发送的DLX
             */
            args.put("x-dead-letter-exchange", TTL_DELAY_EXCHANGE);
            /**
             * 为DLX指定路由键DLK
             */
            args.put("x-dead-letter-routing-key", TTL_DELAY_ROUTING_KEY);
            /**
             * 定义优先级队列,消息最大优先级为15,优先级范围为0-15,数字越大优先级越高
             */
            args.put("x-max-priority", 15);
            /**
             * 设置持久化队列
             */
            return QueueBuilder.durable(TTL_TOPIC_QUEUE).withArguments(args).build();
        }
    
    
        /**
         * 声明Topic类型交换器
         */
        @Bean
        public TopicExchange topicExchange(){
            TopicExchange exchange = new TopicExchange(TTL_TOPIC_EXCHANGE);
            return exchange;
        }
    
        /**
         * Topic交换器和队列通过bindingKey绑定
         * @return
         */
        @Bean
        public Binding bindingTopicExchangeQueue(){
            return BindingBuilder.bind(topicQueue()).to(topicExchange()).with(TTL__TOPIC_ROUTING_KEY);
        }
    
        //============================延迟队列及交换器定义=================================
        /**
         * 定义延迟队列
         */
        @Bean
        publi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值