《RabbitMQ系列教程-第八章-RabbitMQ之TTL队列》

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 《RabbitMQ系列教程-第八章-RabbitMQ之TTL队列》,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

教程说明



RabbitMQ之TTL队列

TTL:全称Time To Live,表示过期时间、存活时间,TTL队列顾名思义就是带有存活时间的队列,在RabbitMQ中,可以对队列或者消息设置过期时间;设置了TTL的Queue中的消息到达TTL时间之前没有被消费将自动删除;在发布消息的时候也可以针对这条消息设置TTL,当队列和消息都设置了TTL时,以时间短的为准;

8.1.1 给队列设置TTL

配置spring.xml:

<!--声明一个队列-->
<rabbit:queue name="test_queue_ttl" id="test_queue_ttl">
    <!--设置queue的参数-->
    <rabbit:queue-arguments>
        <!--x-message-ttl指队列的过期时间 单位:毫秒-->
        <entry key="x-message-ttl" value="2000" value-type="java.lang.Integer"></entry>
    </rabbit:queue-arguments>
</rabbit:queue>

测试代码:

/**
 * TTL:过期时间
 * 		队列统一过期(在创建队列时统一设置过期时间,队列中的消息到达此时间没有被消费自动过期)
 */
@Test
public void testTtl() {

    rabbitTemplate.convertAndSend("test_queue_ttl","ttl....");
}

在这里插入图片描述

发现当消息在队列中2秒中没有被消费将自动清除;

8.1.2 给消息设置TTL

/**
 * TTL:过期时间
 * 2. 消息单独过期
 * <p>
 * 如果设置了消息的过期时间,也设置了队列的过期时间,它以时间短的为准。
 * 队列过期后,会将队列所有消息全部移除。
 */
@Test
public void testTtl2() {
    /*
    // 通过MessageProperties对象配置消息参数
    MessageProperties messageProperties = new MessageProperties();

    //设置消息的过期时间: 2秒
    messageProperties.setExpiration("2000");

    // 封装一条消息
    Message message = new Message("ttl....".getBytes(), messageProperties);

    rabbitTemplate.convertAndSend("test_queue_ttl", message);
    */

    // 通过MessageBuilder对象构建Message
    Message message = MessageBuilder.withBody("ttl...".getBytes()).
            setExpiration("2000")
            .build();
    rabbitTemplate.convertAndSend("test_queue_ttl", message);
}

在使用TTL队列时注意以下几点:

1、当队列和消息都设置了TTL以时间短的为准

2、消息到达过期时间后,只有消息在队列顶端才会被移除掉,而消息只有在要消费的时候才会在队列顶端;

8.1.3 RabbitMQ是如何判断消息过期的?

我们知道一个队列里面是可以存储非常多的消息的,这些消息中有的设置了TTL,有的则没有,那RabbitMQ是如何判断哪些消息是过期了的并且删除该消息的呢?最简单的方法就是轮询了,周期性轮询抽查队列中的所有消息,发现过期了的就进行删除,很显然,这种方法效率太低,RabbitMQ并没有采用这种策略,那RabbitMQ内部是如何进行过期消息的删除呢?

在这里插入图片描述

我们都知道Queue是一个队列,队列是先进先出的,即先到达队列的消息最先消费,假设上图的Message-02消息设置了TTL,并且时间已经到达,但是由于Message-02并不是在队列顶端,因此还会存在队列中

我们做个小测试:

@Test
public void testTtl3() {

    // 消息配置类
    MessageProperties messageProperties = new MessageProperties();
    //设置消息的过期时间,5秒
    messageProperties.setExpiration("2000");

    // 封装一条消息
    Message message = new Message("ttl..".getBytes(), messageProperties);
    for (int i = 1; i <= 4; i++) {
        if (i == 2) {
            // i等于2的时候发送一条带有过期时间的消息
            rabbitTemplate.convertAndSend("test_queue_ttl",message);
        } else {
            rabbitTemplate.convertAndSend("test_queue_ttl", "no ttl...");
        }
    }
}

发现等了很久之后Queue中的消息依旧是4条

在这里插入图片描述
这里需要注意一点:消息过期了就不会被消费了,即使消息还没有被移除队列(消息未在顶部)

8.1.4 TTL队列小结

  • 1)TTL:全称Time To Live,表示设置了过期时间的队列
  • 2)在RabbitMQ中给除了可以给队列设置过期时间还可以给单独的消息设置过期时间;
    • Queue设置TTL:设置x-message-ttl参数,单位:毫秒
    • Message设置TTL:通过MessageProperties对象或者MessageBuilder对象构建消息
  • 3)当QueueMessage都设置了过期时间时以时间短的为准
  • 4)消息到达过期时间并不会立即移除队列,而是要等消息到达Queue顶部RabbitMQ才会移除
  • 5)Message到达了过期时间就不会被再次消费了,即使Message还未到达Queue的顶端;

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131791.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!