死信队列(DLX)
- Dead-Letter-Exchange
- 利用DLX, 当消息在一个队列中变成死信(dead message)之后, 它能被重新publish到另一个Exchange, 这个Exchange就是DLX
- DLX也是一个正常的Exchange, 和一般的Exchange没有区别, 它能在任何队列上被指定, 实际上就是设置某个队列的属性为死信队列
- 当这个队列中有死信时, RabbitMQ就会自动将这个消息重新发布到设置的Exchange上去, 进而被路由到另一个队列
- 可以监听这个队列中消息做相应的处理, 这个特性可以弥补RabbitMQ3.0以前支持的immediate参数的功能
消息变成死信有以下几种情况 :
- 消息被拒绝(basic.reject/basic.nack) 并且requeue重回队列设置成false
- 消息TTL过期
- 队列达到最大长度
死信队列的设置 :
- 首先要设置死信队列的exchange和queue, 然后进行绑定
- Exchange : dlx.exchange
- Queue : dlx.queue
- RoutingKey : #
- 然后正常声明交换机, 队列, 绑定, 只不过需要在队列加上一个扩展参数即可 : arguments.put(“x-dead-letter-exchange”, “dlx.exchange”);
- 这样消息在过期, reject或nack(requeue要设置成false), 队列在达到最大长度时, 消息就可以直接路由到死信队列
代码演示
- 消费者中设置死信队列和正常队列, 启动之后关闭消费者
- 生产者生产的消息一个超时时间, 使消息超时之后变为死信
消费者中设置死信队列
package com.qiyexue.api.dlx;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.util.HashMap;
import java.util.Map;
/**
* 消费者
*
* @author 七夜雪
* @date 2018-12-15 20:07
*/
public class Consumer {
public static void main(String[] args) throws Exception {
// 1. 创建连接工厂并设置属性
ConnectionFactory factory = new ConnectionFactory();;
factory.setHost("192.168.72.138");
factory.setPort(5672);
factory.setVirtualHost("/");
// 2. 创建连接
Connection connection = factory.newConnection();
// 3. 创建channel
Channel channel = connection.createChannel();
// 4. 声明死信队列Exchange和Queue
channel.exchangeDeclare("dlx.exchange", "topic");
channel.queueDeclare("dlx.queue", true, false, false, null);
channel.queueBind("dlx.queue", "dlx.exchange", "#");
// 5. 声明普通Exchange
String exchangeName = "test_dlx_exchange";
String exchangeType = "topic";
String routingKey = "dlx.*";
channel.exchangeDeclare(exchangeName, exchangeType, true, false, null);
// 6. 声明消息队列, 指定死信队列为dlx.exchange
String queueName = "test_dlx_queue";
Map<String, Object> arguments = new HashMap<>();
// x-dead-leeter-exchange属性用于指定死信队列为dlx.exchange
arguments.put("x-dead-letter-exchange", "dlx.exchange");
channel.queueDeclare(queueName, true, false, false, arguments);
// 6. 绑定队列和Exchange
channel.queueBind(queueName, exchangeName, routingKey);
}
}
生产者消息设置超时时间
package com.qiyexue.api.dlx;
import com.rabbitmq.client.*;
import java.util.HashMap;
import java.util.Map;
/**
* 生产者
*
* @author 七夜雪
* @date 2018-12-15 19:56
*/
public class Producer {
public static void main(String[] args) throws Exception {
// 1. 创建ConnectionFactory, 并设置属性
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.72.138");
factory.setPort(5672);
factory.setVirtualHost("/");
// 2. 创建连接
Connection connection = factory.newConnection();
// 3. 创建channel
Channel channel = connection.createChannel();
String exchangeName = "test_dlx_exchange";
String routingKey = "dlx.qiye";
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().expiration("5000").build();
// 发送消息
String msg = "Hello, 七夜雪";
channel.basicPublish(exchangeName, routingKey, true, properties, msg.getBytes());
// 关闭连接
channel.close();
connection.close();
}
}
相关链接
RabbitMQ入门与AMQP协议简介
RabbitMQ成员简介
RabbitMQ高级特性-消息可靠性投递
RabbitMQ高级特性-幂等性保障
RabbitMQ高级特性-Confirm确认消息
RabbitMQ高级特性-Return消息机制
RabbitMQ高级特性-消费端自定义监听
RabbitMQ高级特性-消费端限流
RabbitMQ高级特性-消费端ACK与重回队列
RabbitMQ高级特性-TTL队列/消息
RabbitMQ高级特性-死信队列(DLX)
Spring AMQP整合RabbitMQ
SpringBoot整合RabbitMQ
RabbitMQ集群架构模式介绍
从零开始搭建高可用RabbitMQ镜像模式集群
RabbitMQ集群恢复与故障转移
RabbitMQ-基础组件封装
Git代码地址
慕课网<RabbitMQ消息中间件技术精讲>学习笔记