全部开发者教程

RabbitMQ 入门教程

RabbitMQ 简介
RabbitMQ 简介

RabbitMQ 中TTL消息介绍

1. 前言

Hello,大家好。本小节会为同学们介绍 RabbitMQ 中自带的另一种机制,就是 TTL 消息,以及 TTL 消息队列。TTL 消息和 TTL 消息队列是我们实际工作中使用频率较高的一种机制,这种机制规定了在特定条件下,消息的有效时间,通过应用这种机制,我们可以很灵活地对消息进行控制。

TTL 消息以及 TTL 消息队列这种机制,一般不会单独使用,在实际工作中都会搭配死信队列一并使用,那么在本节中,会首先为同学们介绍何为 TTL 消息以及 TTL 消息队列,在下一节就会为同学们介绍什么是死信队列了。

话不多说,就让我们先来了解一下什么是 TTL 消息吧。

本节主要内容:

  • TTL 消息概述;

2. TTL 消息概述

基础概念:

TTL,全称为 Time to Live ,即生存时间。 说到这个 TTL ,想必大家都有所接触,这个 TTL 并不是 RabbitMQ 中独有的特性,我们在进行应用程序开发时,我们使用的其他工具中,也具备这个生存时间的概念,只不过描述的可能不一样,但是含义相同。那么在 RabbitMQ 中,TTL 描述的又是什么呢?

在 RabbitMQ 中,TTL 这一概念是作用于消息和消息队列上,即为消息以及消息队列规定了一个生存时间,当消息或消息队列的生存时间超过了 TTL 所规定的生存时间之后,消息就会失效,且不会被消费。

其中,对于消息来说,一旦消息的生存时间超过了 TTL 所规定的消息生存时间,那么,这条消息会立即失效,并且不会被任何消费者消费,且会变成一种死信,并最终会被 RabbitMQ 放入死信队列中(相关概念下节介绍,下同)。

而对于消息队列来说,如果消息队列的生存时间超过了 TTL 所规定的消息队列的生存时间,那么消息队列会立即失效,且该消息队列中的消息也会随着消息队列的失效而失效。 这就提醒我们,在对应用程序中的消息进行操作时,可以根据业务需要来设置专门一条消息的生存时间,也可以设置同一消息类型的消息队列的生存时间,以灵活控制消息的有效期限。

从消费者的角度来说,我们也可以这样理解:在消息被设置了 TTL 之后,如果这个消息的等待时间超过了 TTL ,则这个消息就不会被任何消费者消费;从生产者的角度来说,生产者发送了一条消息到 RabbitMQ Server 中,且已经设置了 TTL ,如果这个消息的等待时间超过了 TTL ,即使有消费者来接收消息,这个消息也不会被接收,同时,生产者也不会再次发送相同的消息。

在了解了 TTL 的基础概念之后,我们还需要了解如何通过代码,来配置 TTL 消息。

代码实现:

配置 TTL ,需要我们在生产端进行配置,代码如下:

ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("xx");
connectionFactory.setPort("5672");
connectionFactory.setVirtualHost("/");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChanel();
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
        .deliveryMode(2)
        .expiration("10000")
        .contentEncoding("UTF-8")
        .build();
channel.basicPublish(exchangeName, routingKey, true, properties, msg.getBytes());

代码解释:

第 1-5 行,我们使用 ConnectionFactory 创建了一个客户端连接 RabbitMQ Server 的连接。

第 6 行,我们使用建立好的连接,来创建了一个频道 channel 。

第 7-12 行,我们使用 AMQP.BasicProperties 来初始化了一个具体消息的 properties 参数,初始化 properties 的过程采用了 AMQP 的调用链模式,即通过 AMQP.BasicProperties.Builder() 来对 properties 进行初始化。

其中,deliveryMode 表示 properties 的投递模式,2 表示持久化投递,即 RabbitMQ Server 重启之后依然有效;contentEncoding 表示 properties 的编码模式,这里是支持中文的 UTF-8 格式;expiration 属性就是来对当前的消息设置生存时间的属性,其单位为毫秒,这里设置的 TTL 为 10 秒, 当我们对 properties 的属性设置完毕后,调用 build 方法即可完成 properties 的构建。

第 13 行,我们使用 channel 的 basicPublish 方法,将消息发送到 RabbitMQ Server 中,这里我们直接来看 basicPublish 方法的第四个参数,其他参数已经介绍很多次了,这里不再介绍。

我们都知道,在 RabbitMQ 中,一条具体的消息被分为了消息体和消息参数两个部分, 其中,消息体指的是我们应用程序中的数据,消息参数指的是针对这一应用程序中的数据进行配置的一系列参数,常见的参数有字符集、请求头、投递方式等。basicPublish 方法的第三个参数指的就是一条消息的消息参数,即我们通过调用链模式来构造出的 properties 参数。

将我们构造好的 properties 参数一同发送到 RabbitMQ Server 中,那么,我们配置的 properties 的属性就会生效,即该条消息的 TTL 为 10 秒。

上述代码是配置 TTL 消息的,那么 TTL 消息队列又该如何配置呢,我们看以下代码:

代码实现:

// 省略客户端连接 RabbitMQ Server 代码
Map<String, Object> queueArgumentMap = new HashMap<>();
queueArgumentMap.put("x-message-ttl", "10000");
channel.queueDeclare(queueName, true, true, false, queueArgumentMap);

代码解释:

第 2-3 行,我们声明了一个名为 queueArgumentMap 的 HashMap ,并且指定 key 为 x-message-ttl ,value 为 10000 ,且都是字符串类型。

第 4 行,我们使用 channel 的 queueDeclare 方法,来声明一个队列,这里我们重点看 queueDeclare 方法的第五个参数,这个参数是一个 Map 类型的 arguments 参数,是专门来对队列进行额外配置的参数, 其值就是我们声明的这个 queueArgumentMap 。

在 queueArgumentMap 中,key 为 RabbitMQ 官方规定的设置 TTL 的 key 值,value 即为我们要设置的 TTL 的具体时间,单位为毫秒,这里同样设置为了 10 秒。

Tips: 1.在实际工作中,给消息或者消息队列设置 TTL 是很常见的,所以需要同学们完全掌握本节内容,这样才能在工作中运用自如;
2. queueArgumentMap 中 key 的指定必须要按照 RabbitMQ 官方给出的 key 值来声明,不能自定义声明,否则,将不会起到任何作用;
3. 在为消息或消息队列设置了 TTL 之后,如果我们想要看到直观地结果,我们可以自行编写一个测试程序,并结合 RabbitMQ 的消息管控台来观察,这样效果会很明显。

3. 小结

本小节为同学们介绍了 RabbitMQ 中,如何为消息以及消息队列设置 TTL 生存时间。从 TTL 的基础概念开始,到 TTL 消息以及 TTL 消息队列的编码实现结束,详细介绍了 TTL 是什么、TTL 的作用,以及不同组件下如何配置 TTL ,TTL 在实际工作中应用较多,希望同学们可以完全掌握通过代码的方式来对消息和消息队列配置 TTL ,这样我们才能对消息更加灵活地进行配置。