Direct 交换机
Direct交换机通过路由键精确匹配实现点对点消息路由,是RabbitMQ最常用的交换机类型之一。
定义
Direct交换机将消息路由到绑定队列中路由键与消息路由键完全匹配的队列。匹配规则为严格相等(exact match),不支持通配符或模式匹配。
核心机制
路由匹配流程
- 生产者发送消息时指定Exchange和Routing Key
- Direct交换机接收消息并提取Routing Key
- 遍历所有绑定队列,查找Routing Key完全匹配的绑定关系
- 将消息投递到匹配的队列(通常只有一个)
声明与绑定
Java
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class DirectExchangeExample {
private static final String EXCHANGE_NAME = "direct_logs";
private static final String QUEUE_NAME = "error_queue";
private static final String ROUTING_KEY = "error";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 声明Direct交换机
channel.exchangeDeclare(EXCHANGE_NAME, "direct", true);
// 声明队列
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
// 绑定队列到交换机,指定路由键
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);
// 发布消息
String message = "System error occurred";
channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, null,
message.getBytes("UTF-8"));
System.out.println("Message sent: " + message);
}
}
}
多路由键绑定
一个队列可以绑定到同一Direct交换机的多个路由键:
Java
// 绑定多个路由键到同一队列
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "error");
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "critical");
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "fatal");
注意:队列将接收来自这3个路由键的所有消息,适用于需要聚合多种类型消息的场景。
消费者示例
Java
import com.rabbitmq.client.*;
import java.io.IOException;
public class DirectConsumer {
private static final String EXCHANGE_NAME = "direct_logs";
private static final String QUEUE_NAME = "error_queue";
private static final String ROUTING_KEY = "error";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "direct", true);
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);
System.out.println("Waiting for messages...");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("Received: " + message);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
};
channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});
}
}
注意事项
- Direct交换机仅支持精确匹配,路由键必须完全一致才能匹配成功
- 若消息路由键无匹配队列,消息将被丢弃或返回生产者(取决于mandatory标志)
- 路由键区分大小写,"error"与"Error"视为不同路由键
- 适用于日志分级、任务分发、命令路由等需要精确路由的场景
- 声明交换机时应指定
durable=true保证重启后交换机不丢失
要点总结
- Direct交换机通过路由键精确匹配实现点对点路由
- 路由键必须完全相等才能匹配,不支持通配符
- 一个队列可绑定多个路由键接收多种消息
- 无匹配队列时消息默认被丢弃,需合理设计路由策略
- 适用于日志系统、任务分发、精确路由等场景
文章存放路径:D:\git2\jwdev\articles\RABBITMQ\进阶\交换机类型详解\Direct 交换机.md
📝 发现内容有误?点击此处直接编辑