死信的来源:
(1)消息TTL过期
(2)队列满了
(3)消息被拒绝(basic.reject 或 basic.nack)并且requeue=false
死信队列:放死信的队列称为死信队列
应用:在商城下单成功并点击去支付后在指定时
间未支付时自动失效->放入死信队列
主体代码思路:
c1:
声明交换机:normal_exchange、dead_exchange
声明队列:normal_queue、dead_queue(定义normal_queue时额外指定死信的交换机与路由)
绑定交换机与队列:normal_exchange&normal_queue、dead_exchange&dead_queue
//声明交换机 类型为direct
channel.exchangeDeclare(NORMAL_EXCHANGE, BuiltinExchangeType.DIRECT);
channel.exchangeDeclare(DEAD_EXCHANGE, BuiltinExchangeType.DIRECT);
//声明队列
channel.queueDeclare(DEAD_QUEUE, false, false, false, null);
Map<String, Object> params = new HashMap<>();
params.put("x-dead-letter-exchange", DEAD_EXCHANGE);
params.put("x-dead-letter-routing-key", "lisi");
channel.queueDeclare(NORMAL_QUEUE, false, false, false, params);
//绑定交换机与队列
channel.queueBind(DEAD_QUEUE, DEAD_EXCHANGE, "lisi");
channel.queueBind(NORMAL_QUEUE, NORMAL_EXCHANGE, "zhangsan");
1.消息TTL过期
producer端发送消息时设置消息的TTL时间(Time To Live)
//设置消息的 TTL 时间
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().expiration("10000").build();
channel.basicPublish(NORMAL_EXCHANGE, "zhangsan", properties, message.getBytes());
2.队列满了
Map<String, Object> params = new HashMap<>();
params.put("x-max-length", 6);
//设置队列最大长度
params.put("x-dead-letter-exchange", DEAD_EXCHANGE);
params.put("x-dead-letter-routing-key", "lisi");
channel.queueDeclare(NORMAL_QUEUE, false, false, false, params);
3.消息被拒并不放回队列
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
if (message.equals("info5")) {
System.out.println("Consumer接收到消息:" + message + ",并拒绝签收该消息");
//requeue=false不重新入队,如果配置了死信交换机将发送到死信队列中
channel.basicReject(delivery.getEnvelope().getDeliveryTag(), false);
} else {
System.out.println("Consumer接收到消息:" + message);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
};
RabbitMQ 死信队列
最新推荐文章于 2023-05-25 01:29:07 发布
本文介绍了RabbitMQ中死信的来源,包括消息TTL过期、队列满和消息被拒绝且不重新入队,并详细展示了如何设置死信队列。通过实例展示了如何在代码中声明交换机、队列和绑定,以及如何处理消息过期和队列满的情况。此外,还给出了消息被消费者拒绝的处理方式。
摘要由CSDN通过智能技术生成