TTL 消息过期
TTL(Time To Live)用于控制消息的最大存活时间,超时后消息自动过期成为死信。
两种 TTL 设置方式
方式一:队列级别 TTL
队列中所有消息共享同一个 TTL,通过队列参数 x-message-ttl 设置。
Java
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;
public class QueueTtlExample {
private static final String TTL_QUEUE = "ttl.queue";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 设置队列 TTL 为 30 秒(30000 毫秒)
Map<String, Object> args = new HashMap<>();
args.put("x-message-ttl", 30000);
channel.queueDeclare(TTL_QUEUE, true, false, false, args);
System.out.println("队列 TTL 队列声明完成,消息将在 30 秒后过期");
}
}
}
方式二:消息级别 TTL
每条消息独立设置 TTL,通过发送消息时设置 expiration 属性。
Java
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;
public class MessageTtlExample {
private static final String EXCHANGE = "ttl.exchange";
private static final String QUEUE = "ttl.queue";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
channel.exchangeDeclare(EXCHANGE, BuiltinExchangeType.DIRECT, true);
channel.queueDeclare(QUEUE, true, false, false, null);
channel.queueBind(QUEUE, EXCHANGE, "ttl.key");
String message = "Hello TTL RabbitMQ";
// 设置消息 TTL 为 60 秒(60000 毫秒)
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
.expiration("60000")
.build();
channel.basicPublish(EXCHANGE, "ttl.key", props,
message.getBytes(StandardCharsets.UTF_8));
System.out.println("消息已发送,TTL: 60s");
}
}
}
两种方式的差异
| 对比项 | 队列 TTL | 消息 TTL |
|---|---|---|
| 设置位置 | 队列声明时 | 消息发送时 |
| 粒度 | 队列级别(统一) | 消息级别(独立) |
| 过期检查时机 | 消息到达队列头部时 | 消息投递到消费者时 |
| 性能 | 更高(批量处理) | 较低(逐条检查) |
当同时设置队列 TTL 和消息 TTL 时,以较小值为准。
注意事项
- TTL 值为 毫秒,不支持秒级单位
- 消息过期后不会立即删除,RabbitMQ 仅在消息到达队列头部时检查
- 消息级别 TTL 的
expiration必须是 字符串 类型,不是 Long - TTL 过期的消息进入死信队列时,
x-death中 reason 为expired
要点总结
- 队列 TTL 通过
x-message-ttl参数设置,影响队列所有消息 - 消息 TTL 通过
expiration属性设置,支持每条消息独立过期时间 - 同时设置时取较小值
expiration必须是字符串类型的毫秒数- TTL 过期是消息成为死信的条件之一
📝 发现内容有误?点击此处直接编辑