回顾RabbitMQ实现消息延迟

一 概述

         在RabbitMQ中,默认情况下,消息在没有设置消息过期的参数的时候是不会过期的,即使消息没有被消费掉,消息会一直存储在队列中。

二 队列消息存活时间TTL

        TTL(Time-To-Live),消息存活的时间,即消息的有效期。我们可以通过设置TTL来实现消息有一个存活时间的需求。当这个消息的存活时间超过了TTL并且还没有被消费,那么该消息就会变成死信。

        TTL的设置:

        1. 在我们声明队列时,在属性中进行消息有效期设置,这种情况下,所有进入该队列的消息都会有一个相同的有效期。(对于这种方式,当消息队列设置过期时间的时候,那么消息过期了就会被删除,因为消息进入RabbitMQ之后时存在一个消息队列中,队列的头部为最早的消息,此时,队列只需要一个定时让任务,从头部开始扫描是否有过期消息,有则直接删除。

        配置类中设置队列消息过期:

@Bean
Queue queue() {
    Map<String, Object> args = new HashMap<>();
    args.put("x-message-ttl", 10000);
    return new Queue(QUEUE_DEMO, true, false, false, args);
}

       消息发送:

@RestController
public class TestController {
    @Autowired
    RabbitTemplate rabbitTemplate;

    @GetMapping("/test")
    public void test() {
        Message message = MessageBuilder.withBody("test queue".getBytes())
                .build();
        rabbitTemplate.convertAndSend(QueueConfig.QUEUE_DEMO, message);
    }
}

        效果:

        

         此时在队列中的Features属性中存在D(消息队列中的消息持久化)和TTL(消息过期设置)信息。

        2.在我们发送消息时对消息的有效期进行设置,这样不同的消息会因为设置的不同而有不同的有效期。(与设置消息队列过期时间不同,该方式在消息过期之后也不会立即被删除,而是当消息投递给消费者的时候才会被删除。由于该方式所声明不同消息的有效期是不一样的,此时当要知道哪条消息过期就要进行队列消息遍历,当消息比较多时就比较消耗性能。)        

        注意:当两种情况都设置了,则消息会将较短的是时间左右消息的有效期。

三 消息队列的配置类

@Configuration
public class QueueConfig {

    //队列
    public static final String QUEUE_DEMO = "queue_demo";
    //交换机
    public static final String JEXCHANGE_DEMO = "exchange_demo";
    public static final String ROUTING_KEY = "routing_key";

    @Bean
    Queue queue() {
        return new Queue(QUEUE_DEMO, true, false, false);
    }

    @Bean
    DirectExchange directExchange() {
        return new DirectExchange(EXCHANGE_DEMO, true, false);
    }

    @Bean
    Binding binding() {
        return BindingBuilder.bind(queue())
                .to(directExchange())
                .with(ROUTING_KEY);
    }
}

        配置类分析:

        1. 配一个消息队列,new一个Queue:

           new Queue(参数一:队列的名称,参数二:消息队列中的消息是否持久化,参数三:消息队列是否存在排他性(一般为false),参数四:当消息队列中不存在任何订阅的消费者时,该队列是否自动删除(适用于临时队列))。

        2. 配置交换机,new一个DirectExchange。

        3. 将交换机和队列绑定在一起。

四 队列中消息发送接口

@RestController
public class TestController {
    @Autowired
    RabbitTemplate rabbitTemplate;

    @GetMapping("/test")
    public void test() {
        Message message = MessageBuilder.withBody("test queue".getBytes())
                .setExpiration("10000")
                .build();
        rabbitTemplate.convertAndSend(QueueConfig.QUEUE_DEMO, message);
    }
}

        在创建消息对象的时候设置10秒的过期时间。

 参考资料:RabbitMQ 中的消息会过期吗? (qq.com)icon-default.png?t=L9C2https://mp.weixin.qq.com/s?__biz=MzI1NDY0MTkzNQ==&mid=2247494827&idx=1&sn=c7e6d24cc9ce7d21f3f450a41b565ddf&scene=21#wechat_redirect

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值