死信交换机: DLX,dead-letter-exchange
当消息在一个队列中变成死信 (dead message) 之后,它能被重新 publish 到另一个 队列
消息变成死信的原因有:
1.消息被拒绝 (basic.reject / basic.nack) 并且 reQueue=false
2.消息 TTL 过期
3.队列达到最大长度了
死信队列的使用场景
可以用做定时任务,也可以是存储超时消息,比如付费超时之类的
私信队列的使用
- 直接在管理页面上创建
首先创建私信交换机demo.dead
再创建私信队列demo.dead
绑定队列和交换器
创建业务交换器demo
创建业务队列demo
x-message-ttl: 指定消息超时时间是10000ms
x-dead-letter-exchange: 指定死信交换器为demo.dead
x-dead-letter-routing-key: 指定死信的routingKey是demo.dead
在绑定业务队列到业务交换器
- springboot应用中创建
public void createQueue(String topic, String queryName) throws IOException {
log.info("create queue : {}, {}, {}", topic, queryName);
RabbitChannelManager.MyChannel channel = rabbitChannelManager.getChannel();
/* 创建死信队列 */
String deadQueueName = addDeadSuffix(queryName);
String deadRouteKey = addDeadSuffix(topic);
channel.getChannel().queueDeclare(deadQueueName, true, false, false, null);
channel.getChannel().queueBind(addDeadSuffix(queryName), rabbitConfiguration.getDeadExchange(), deadRouteKey);
/* 创建队列,加入死信转发参数 */
Map<String, Object> deadArgs = new HashMap<>();
deadArgs.put("x-message-ttl", rabbitConfiguration.getDeadMessageTtl());
deadArgs.put("x-dead-letter-exchange", rabbitConfiguration.getDeadExchange());
deadArgs.put("x-dead-letter-routing-key", deadRouteKey);
channel.getChannel().queueDeclare(queryName, true, false, false, deadArgs);
channel.getChannel().queueBind(queryName, rabbitConfiguration.getDefaultExchange(), topic);
rabbitChannelManager.returnChannel(channel);
}
创建好的队列列表
测试一下
发送一条消息到demo队列,查看队列情况
可以看到demo队列有一条消息
等待一会后再看队列情况
可以看到该消息已经因为超时而转发到了demo.dead死信队列
另外两种情况也是同样的结果就不多写了