【Rabbitmq篇】高级特性----TTL,死信队列,延迟队列

目录

一.TTL

        1.设置消息的TTL

2.设置队列的TTL

3.俩者区别 

二.死信队列

定义:

消息成为死信的原因:

1.消息被拒绝(basic.reject 或 basic.nack)

2.消息过期(TTL)

3.队列达到最大长度 

​编辑 

死信队列的应用场景

三.延迟队列 

 定义:

应用场景 

实现一:TTL+死信队列 

 实现二:延迟队列插件

​编辑 俩种实现对比:


一.TTL

TTL(TimetoLive,过期时间),即过期时间.RabbitMQ可以对消息和队列设置TTL.

它代表消息的存活时间。当一条消息被发送到 RabbitMQ 队列后,TTL 可以限制消息在队列中能够存活的最长时间。一旦消息在队列中的存活时间超过了 TTL 设定的值,消息就会被自动删除。

咱们在网上购物,经常会遇到一个场景,当下单超过24小时还未付款,订单会被自动取消 
申请退款之后,超过7天未被处理,则自动退款

这就是设置了TTL


目前有俩种方式可以设置消息的TTL
一是设置队列的TTL,队列中所有消息都有相同的过期时间.

二是对消息本身进行单独设置,每条消息的TTL可以不同.如果两种方法一起使用,则消息的TTL以两者之间较小的那个数值为准.


先看针对每条消息设置TTL


1.设置消息的TTL

1)配置交换机&队列

    //TTL
    public static final String TTL_QUEUE = "ttl.queue";
    public static final String TTL_EXCHANGE = "ttl.exchange";
    //TTL
    @Bean("ttlQueue")
    public Queue ttlQueue() {
        return QueueBuilder.durable(Constants.TTL_QUEUE).build();
    }
    @Bean("ttlExchange")
    public DirectExchange ttlExchange() {
        return  ExchangeBuilder.directExchange(Constants.TTL_EXCHANGE).build();
    }
    @Bean("ttlBinding")
    public Binding ttlBinding(@Qualifier("ttlQueue") Queue queue,@Qualifier("ttlExchange") DirectExchange directExchange) {
        return BindingBuilder.bind(queue).to(directExchange).with("ttl");
    }

2)发送消息

        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setExpiration("10000");//单位为毫秒,设置10秒后过期
                return message;
            }
        };
MessagePostProcessor中 重写postProcessMessage 方法

可以设置它的过期时间

这里使用了lambda表达式

    @RequestMapping("/ttl")
    public String ttl() {
        System.out.println("ttl!!!");
        rabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE,"ttl","ttl test...", message -> {
            message.getMessageProperties().setExpiration("10000");//单位为毫秒,设置10秒后过期
            return message;
        });
        return "消息发送成功";
    }

3)测试

十秒钟过后结果:

 自动消失了这条消息

如果不设置TTL,则表示此消息不会过期;如果将TTL设置为0,则表示除非此时可以直接将消息投递到消费者,否则该消息会被立即丢弃.


2.设置队列的TTL

设置队列TTL的方法是在创建队列时,加⼊ x-message-ttl 参数实现的,单位是毫秒

1)配置队列和绑定关系

    public static final String TTL_QUEUE2= "ttl.queue2";
    @Bean("ttlQueue2")
    public Queue ttlQueue2() {
        return QueueBuilder.durable(Constants.TTL_QUEUE2).ttl(20000).build();
    }
    @Bean("ttlBinding2")
    public Binding ttlBinding2(@Qualifier("ttlQueue2") Queue queue,@Qualifier("ttlExchange") DirectExchange directExchange) {
        return BindingBuilder.bind(queue).to(directExchange).with("ttl");
    }

2)发送消息

    @RequestMapping("/ttl2")
    public String ttl2() {
        System.out.println("ttl2!!!");
        rabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE,"ttl","ttl2 test 20s...");
        return "消息发送成功";
    }

 3)测试

20s后结果: 

因为绑定的交换机是同一个,并且routingKey也是同一个,所有会向Q1和Q2同时发消息

我们发送的普通消息 并没有设置带有TTL的消息  

所有Q1并不会消失 而Q2设置了队列的TTL,所以会消失。

4)测试2

如果发送消息的TTL(10s过期)给设置了TTL(20s过期)的队列,会发生什么结果?

结论:10s后俩个队列里面的消息全部消失,所有可得知取 它最短的时间过期

3.俩者区别 

设置队列TTL属性的方法,一旦消息过期,就会从队列中删除
设置消息TTL的方法,即使消息过期,也不会马上从队列中删除,而是在即将投递到消费者之前进行判定的.

为什么这两种方法处理的方式不⼀样?
因为设置队列过期时间,队列中已过期的消息肯定在队列头部,RabbitMQ只要定期从队头开始扫描是否有过期的消息即可.
而设置消息TTL的方式每条消息的过期时间不同,如果要删除所有过期消息需要扫描整个队列,所以不如等到此消息即将被消费时再判定是否过期,如果过期再进行删除即可.

<
转载请说明出处内容投诉
CSS教程网 » 【Rabbitmq篇】高级特性----TTL,死信队列,延迟队列

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买