Springboot与RabbitMQ上手之消息超时时间、队列消息超时时间(五)

前言

目的主要是学习RabbitMQ的消息超时时间、队列消息超时时间,大概会简单介绍学习为主:毕竟还是要来演示Springboot整合RabbitMQ注解的方式来使用。

一、TTL(过期时间)

TTL是 Time-To-Live 的缩写,RabbitMQ可以对消息和队列设置TTL(过期时间)。
RabbitMQ针对队列中的消息过期时间(Time To Live, TTL)有两种方法可以设置。
第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。
第二种方法是对消息进行单独设置,每条消息TTL可以不同。如果上述两种方法同时使用,则消息的过期时间以两者之间TTL较小的那个数值为准。消息在队列的生存时间一旦超过设置的TTL值,就成为dead message,消费者将无法再收到该消息。

二、为单条消息设置TTL(超时时间)

针对单条消息设置TTL的方法是MessagePostProcessor对象里setExpiration(过期时间)

  1. 当队列消息的TTL 和消息TTL都被设置,时间短的TTL设置生效。
  2. 为消息设置TTL有一个问题:RabbitMQ只对处于队头的消息判断是否过期(即不会扫描队列),所以,很可能队列中已存在死消息,但是队列并不知情。这会影响队列统计数据的正确性,妨碍队列及时释放资源。
  rabbitTemplate.convertAndSend("timeOut.exchange.test","key.time.out",messageProperties,
            // 设置消息过期时间: 单位:毫秒
                message1 -> {
                message1.getMessageProperties().setExpiration("10000");// 过期时间
                message1.getMessageProperties().setDeliveryMode(MessageDeliveryMode.fromInt(2)); // 持久化
            // 返回消息对象
                return message1;
                },correlationData);

三、为队列设置TTL(超时时间)

通过队列属性设置消息TTL,在声明队列方法中加入x-message-ttl参数实现的,这个参数的单位是毫秒。
1)过期时间单位也是毫秒,但是与消息TTL不同在于 队列TTL值必须大于零

    /* 设置队列过期时间*/
    @Bean
    public Exchange queueTimeOutExchange(){
        return new DirectExchange("queueTimeOut.exchange.test",true,false);
    }

    // 声明过期的队列并定义队列名称
    @Bean
    public Queue queueTimeOutQueue(){
        // 消息过期 特殊的args
        Map args  = new HashMap<>(16);
        args.put("x-message-ttl",20000);
          // 设置队列可以存储的最大消息数量
        args.put("x-max-length", 10);
        return new Queue("queueTimeOut.queue.test"
                ,true,false,false,args);
    }

    @Bean
    public Binding queueTimeOutBinding(){
        return new Binding("queueTimeOut.queue.test",
                Binding.DestinationType.QUEUE,
                "queueTimeOut.exchange.test",
                "key.queuetime.out",null);
    }

四.总结

4.1 对于第一种消息设置过期时间:
message1.getMessageProperties().setExpiration("10000");// 过期时间

每条消息的过期时间不同,如果要删除所有过期消息,势必要扫描整个队列,所以不如等到此消息即将被消费时再判定是否过期,如果过期,再进行删除。

4.2 对于第二种队列设置过期时间:
    @Bean
    public Queue queueTimeOutQueue(){
        // 消息过期 特殊的args
        Map args  = new HashMap<>(16);
        args.put("x-message-ttl",20000);
          // 设置队列可以存储的最大消息数量
        args.put("x-max-length", 10);
        return new Queue("queueTimeOut.queue.test"
                ,true,false,false,args);
    }

一旦消息过期,就会从队列中抹去。因为队列中已过期的消息肯定在队列头部,RabbitMQ只要定期从队头开始扫描是否有过期消息即可。

你可能感兴趣的:(Springboot与RabbitMQ上手之消息超时时间、队列消息超时时间(五))