RabbitMQ 过期时间(TTL)

TTL,Time to Live的简称,即过期时间,RabbitMQ可以对消息和队列设置TTL。

RabbitMQ支持设置队列的过期时间和消息的过期时间。如果设置队列的过期时间则队列中所有的消息都有相同的过期时间。如果设置消息的过期时间则每条消息的过期时间则可以不同。如两个方法一起使用,则消息的TTL取最小的数值为重。消息在队列中的生存时间一旦超过了TTL值,则会变成死信,死信消息将被从原有队列中移除。

设置队列的过期时间

针对队列设置过期时间RabbitMQ提供了三种设置方式:

  • 代码定义队列时设置x-message-ttl属性
  • 通过Policy方法设置
  • 通过调用HTTP API的方式设置(RabbitMQ管理工具)

在大多数情况定义队列(代码定义)的过程中设置队列的过期时间就足够使用,方法2 3只要适用于不通过代码定义队列的场景,在这里不进行详细讲述。java实现中定义队列的方法如下

java 复制代码
    /**
     * Declare a queue
     * @param queue the name of the queue   队列的名称
     * @param durable true if we are declaring a durable queue (the queue will survive a server restart) 是否持久化
     * @param exclusive true if we are declaring an exclusive queue (restricted to this connection) 是否独占队列(仅限于此连接)
     * @param autoDelete true if we are declaring an autodelete queue (server will delete it when no longer in use)  是否自动删除队列(服务器将在不再使用时删除它)
     * @param arguments other properties (construction arguments) for the queue  队列的其他属性(构造参数)
     * @return a declaration-confirm method to indicate the queue was successfully declared
     * @throws java.io.IOException if an error is encountered
     */
    Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
                                 Map<String, Object> arguments) throws IOException;

从定义队列方法中不难看出,如果想要实现设置TTL参数,则需要从Map<String, Object> arguments入手。该参数为一个Map键值对。设置TTL的代码实现如下:

java 复制代码
Map<String,Object> arguments = new HashMap<>();
arguments.put("x-message-ttl",6000);
channel.queueDeclare(queue,durable,exclusive,autoDelete,arguments);

如果不给队列设置TTL,则按照消息的TTL进行处理,如果队列和消息都未设置TTL,则表明该消息不会过期,如果将TTL设置为0,则便是除非此时可以直接将消息投递给消费者,否则消息会被丢失。

设置消息的过期时间

给消息设置过期时间及给每一条发送的消息分别设置过期时间,因此这个TTL在发送消息的时候继续设置。发送消息的方法如下:

java 复制代码
    /**
     * Publish a message.
     * @param exchange the exchange to publish the message to 交换机名称
     * @param routingKey the routing key 路由键(交换机将消息存储到队列的依据)
     * @param mandatory true if the 'mandatory' flag is to be set 是否强制的(如果不存在存放消息的队列则将消息重新返回给生产者)
     * @param immediate true if the 'immediate' flag is to be
     * set. Note that the RabbitMQ server does not support this flag. (消息是否立即发送,RabbitMQ 3.0后弃用)
     * @param props other properties for the message - routing headers etc 消息的其他配置(路由标头等)
     * @param body the message body 消息内容
     * @throws java.io.IOException if an error is encountered
     */
    void basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body)
            throws IOException;

从定义队列方法中不难看出,如果想要实现设置TTL参数,则需要从BasicProperties props入手。该类的具体参数如下:

java 复制代码
        public static final class Builder {
            private String contentType;
            private String contentEncoding;
            private Map<String,Object> headers;
            // 是否持久化
            private Integer deliveryMode;
            private Integer priority;
            private String correlationId;
            private String replyTo;
            // 消息过期时间
            private String expiration;
            private String messageId;
            private Date timestamp;
            private String type;
            private String userId;
            private String appId;
            private String clusterId;

根据上述内容,我们可以通过设置expiration的方法实现设置消息过期时间。

java 复制代码
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
builder.deliveryMode(2);
builder.expiration("2000");
AMQP.BasicProperties properties = builder.build();            channel.basicPublish(EXCHANGE_NAME,ROUTING_KEY,properties,message.getBytes());

需要注意的是RabbitMQ中的队列是一个先入先出的队列,而一个小时是否到达过期时间时当该消息即将被投放的时候进行判断,也就是说RabbiMQ没有必要轮询队列中所有的消息是否到底过期时间,仅需要判断即将发送的消息是否到达过期时间,如果到达过期时间则将该消息丢弃即可**。因此如果一个队列中的消息的过期时间各不相同,那么并不是一旦消息到达过期时间则从队列中丢失,只有该消息将被发送的时候才会被丢弃**。

相关推荐
月夜星辉雪3 小时前
【RabbitMQ 项目】服务端:路由交换模块
分布式·rabbitmq
super_journey3 小时前
RabbitMq中交换机(Exchange)、队列(Queue)和路由键(Routing Key)
分布式·中间件·rabbitmq
王彬泽5 小时前
【RabbitMQ】重试机制、TTL
rabbitmq·ttl·重试机制
海里真的有鱼8 小时前
Spring Boot 项目中整合 RabbitMQ,使用死信队列(Dead Letter Exchange, DLX)实现延迟队列功能
开发语言·后端·rabbitmq
小宋102111 小时前
玩转RabbitMQ声明队列交换机、消息转换器
服务器·分布式·rabbitmq
xcx0031 天前
快充协议方案,Type-C接口受电端Sink取电快充协议芯片
zookeeper·rabbitmq·flume·memcached·storm
杰信步迈入C++之路1 天前
【RabbitMQ】快速上手
分布式·rabbitmq·ruby
c1tenj21 天前
docker创建rabbitmq容器
java·rabbitmq·java-rabbitmq
sdg_advance1 天前
RabbitMQ消费者确认和重复机制
rabbitmq·java-rabbitmq
小宋10211 天前
RabbitMQ:交换机详解(Fanout交换机、Direct交换机、Topic交换机)
服务器·网络·rabbitmq