1 图解
死信队列
2 消息如何进入死信队列
消息过期
队列长度已满(会将第一条消息放入死信队列)
消息被拒绝且不再重新尝试
3 应用场景
在定义业务队列时,指定一个死信交换机,并绑定一个死信队列
当消息变成死信时,该消息就会被发送到该死信队列上
这样就方便我们查看消息失败的原因
4 代码样例
4.1 生产者
/**
* 定义死信队列相关信息
*/
public final static String deadQueueName = "dead_queue";
public final static String deadRoutingKey = "dead_routing_key";
public final static String deadExchangeName = "dead_exchange";
/**
* 死信队列 交换机标识符
*/
public static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange";
/**
* 死信队列交换机绑定键标识符
*/
public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";
// 邮件队列
private String FANOUT_EMAIL_QUEUE = "fanout_queue";
/**
* 配置死信队列
*
* @return
*/
@Bean
public Queue deadQueue() {
Queue queue = new Queue(deadQueueName, true);
return queue;
}
/*
* 创建死信交换机
*/
@Bean
public DirectExchange deadExchange() {
return new DirectExchange(deadExchangeName);
}
/*
* 将死信队列与死信交换机绑定
*/
@Bean
public Binding bindingDeadExchange(Queue deadQueue, DirectExchange deadExchange) {
return BindingBuilder.bind(deadQueue).to(deadExchange).with(deadRoutingKey);
}
/**
* 声明业务队列,将死信交换机与队列进行绑定
* @return Queue
*/
@Bean
public Queue fanOutQueue() {
Map<String, Object> args = new HashMap<>(2);
args.put(DEAD_LETTER_QUEUE_KEY, deadExchangeName);
args.put(DEAD_LETTER_ROUTING_KEY, deadRoutingKey);
return new Queue(FANOUT_EMAIL_QUEUE, true, false, false, args);
}
4.2 消费者
try {
// 通知mq服务器删除该消息
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e) {
// 消息放入死信队列
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
}
5 注意事项
如果创建队列时,未绑定死信交换机,如果想要绑定,需要将队列删除,重新创建
网友评论