概述
过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取;过了之后消息将自动被删除。RabbitMQ可以对消息和队列设置TTL。目前有两种方法可以设置。
- 第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。
- 第二种方法是对消息进行单独设置,每条消息TTL可以不同。
如果上述两种方法同时使用,则消息的过期时间以两者之间TTL较小的那个数值为准。消息在队列的生存时间一旦超过设置的TTL值,就称为dead message被投递到死信队列, 消费者将无法再收到该消息。
设置队列TTL
参数 x-message-ttl 的值 必须是非负 32 位整数 (0 <= n <= 2^32-1) ,以毫秒为单位表示 TTL 的值。这样,值 6000 表示存在于 队列 中的当前 消息 将最多只存活 6 秒钟。
package com.chif.rabbitmq.springbootorderrabbitmqproducer.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
@Configuration
public class TTLRabbitMqConfiguration {
//1.声明注册fanout模式的交换机
@Bean
public DirectExchange ttlDirectExchange() {
return new DirectExchange("ttl_order_exchange", true, false);
}
//2.声明队列 sms.direct.queue,email.direct.queue,duanxin.direct.queue
@Bean
public Queue ttlDirectQueue() {
//设置ttl过期时间
HashMap<String, Object> args = new HashMap();
args.put("x-message-ttl",5000);
//设置死信队列的交换机和队列routingKey
args.put("x-dead-letter-exchange","dead_direct_exchange");
args.put("x-dead-letter-routing-key","dead");
//设置队列的最大长度
args.put("x-max-length",5);
return new Queue("ttl.direct.queue", true,false,false,args);
}
@Bean
public Queue ttlDirectMessageQueue() {
//从MessagePostProcessor设置ttl过期时间
return new Queue("ttlMsg.direct.queue", true);
}
//3.完成绑定关系
@Bean
public Binding ttlDirectBinding() {
return BindingBuilder.bind(ttlDirectQueue()).to(ttlDirectExchange()).with("ttl");
}
@Bean
public Binding ttlDirectMsgBinding() {
return BindingBuilder.bind(ttlDirectMessageQueue()).to(ttlDirectExchange()).with("TTLMsg");
}
}
设置消息TTL
消息的过期时间;只需要在发送消息(可以发送到任何队列,不管该队列是否属于某个交换机)的时候设置过期时间即可。在生产者发送消息时传入MessagePostProcessor 类,并设置过期时间到队列:
package com.chif.rabbitmq.springbootorderrabbitmqproducer.service;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.UUID;
@Service
public class OrderService {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 模拟用户下单
* @param userId
* @param productId
* @param num
*/
public void makeOrderTTLMessage(String userId, String productId, int num) {
//1.根据商品id查询库存是否重组
//2.保存订单
String orderId = UUID.randomUUID().toString();
System.out.println("订单生产成功"+orderId);
//3.通过MQ来完成消息的分发
/*
* 参数1:交换机
* 参数2:路由key/queue队列名称
*/
String exchangeName = "ttl_order_exchange";
String routingKey="TTLMsg";
//给消息设置过期时间
MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
//这里就是字符串
message.getMessageProperties().setExpiration("5000");
message.getMessageProperties().setContentEncoding("UTF-8");
return message;
}
};
rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId,messagePostProcessor);
}
}