大家好,我是工藤学编程 🦉 | 一个正在努力学习的小博主,期待你的关注 |
|---|---|
实战代码系列最新文章😉 | C++实现图书管理系统(Qt C++ GUI界面版) |
SpringBoot实战系列🐷 | 【SpringBoot实战系列】SpringBoot3.X 整合 MinIO 存储原生方案 |
分库分表 | 分库分表之实战-sharding-JDBC分库分表执行流程原理剖析 |
消息队列 | 深入浅出 RabbitMQ-交换机详解与发布订阅模型实战 |
前情摘要:
1、深入浅出 RabbitMQ-核心概念介绍与容器化部署 2、深入浅出 RabbitMQ-简单队列实战 3、深入浅出 RabbitMQ-工作队列实战(轮训策略VS公平策略) 4、深入浅出 RabbitMQ-交换机详解与发布订阅模型实战
【亲测宝藏】发现一个让 AI 学习秒变轻松的神站!不用啃高数、不用怕编程,高中生都能看懂的人工智能教程来啦!
👉点击跳转,和 thousands of 小伙伴一起用快乐学习法征服 AI,说不定下一个开发出爆款 AI 程序的就是你!
在消息中间件的世界里,RabbitMQ的路由机制堪称灵活调度的典范。今天我们聚焦其中的「路由模式」(Routing),聊聊它如何像精准的导航系统一样,让消息按规则抵达目的地。
路由模式是RabbitMQ中一种基于「标签匹配」的消息分发机制。它的核心逻辑是:消息通过指定的“路由键”(Routing Key),被交换机精准转发到绑定了相同键值的队列。
与广播模式(Fanout)不同,路由模式不会“雨露均沾”——只有当消息的Routing Key与队列绑定的Binding Key完全匹配时,消息才会被投递。这种特性让它成为需要“定向处理消息”场景的理想选择。
Direct类型(直连交换机),它是路由模式的“调度中心”。Binding Key(可理解为队列“感兴趣的标签”)。Routing Key(消息的“标签”)。简单说,这就像快递分拣:Binding Key是“收件地址”,Routing Key是“快递面单地址”,交换机则是“分拣员”,只把快递送到地址完全匹配的站点。
最经典的应用莫过于日志采集系统(如ELK stack):
log_exchange)。alert_queue)绑定Binding Key为error。store_queue)绑定Binding Key为error、info、debug。error)。这样一来,error日志会同时进入两个队列(既告警又存储),而info/debug日志仅进入存储队列,完美满足差异化需求。
下面用Java代码演示完整流程,基于RabbitMQ Java Client 5.x。
public class LogProducer {
private static final String EXCHANGE_NAME = "log_direct_exchange";
public static void main(String[] args) throws Exception {
// 1. 创建连接工厂并配置
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.229.128");
factory.setUsername("admin");
factory.setPassword("password");
factory.setVirtualHost("/dev");
factory.setPort(5672);
// 2. 建立连接和信道
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 3. 声明Direct交换机
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
// 4. 准备不同级别的日志消息
String errorLog = "【ERROR】数据库连接失败";
String infoLog = "【INFO】用户登录成功";
String debugLog = "【DEBUG】SQL执行耗时: 20ms";
// 5. 发送消息并指定Routing Key
channel.basicPublish(EXCHANGE_NAME, "error", null, errorLog.getBytes());
channel.basicPublish(EXCHANGE_NAME, "info", null, infoLog.getBytes());
channel.basicPublish(EXCHANGE_NAME, "debug", null, debugLog.getBytes());
System.out.println("日志消息发送完成");
}
}
}public class LogStorageConsumer {
private static final String EXCHANGE_NAME = "log_direct_exchange";
public static void main(String[] args) throws Exception {
// 1. 配置连接(同生产者)
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.229.128");
factory.setUsername("admin");
factory.setPassword("password");
factory.setVirtualHost("/dev");
factory.setPort(5672);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 2. 声明交换机(与生产者保持一致)
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
// 3. 创建临时队列并绑定多个Routing Key
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, EXCHANGE_NAME, "error"); // 接收error日志
channel.queueBind(queueName, EXCHANGE_NAME, "info"); // 接收info日志
channel.queueBind(queueName, EXCHANGE_NAME, "debug"); // 接收debug日志
// 4. 消费消息(存储逻辑)
DeliverCallback callback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("[存储服务] 收到日志: " + message);
};
channel.basicConsume(queueName, true, callback, consumerTag -> {});
}
}public class ErrorAlertConsumer {
private static final String EXCHANGE_NAME = "log_direct_exchange";
public static void main(String[] args) throws Exception {
// 连接配置同上
ConnectionFactory factory = new ConnectionFactory();
// ...省略连接参数
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
String queueName = channel.queueDeclare().getQueue();
// 只绑定error路由键
channel.queueBind(queueName, EXCHANGE_NAME, "error");
// 消费消息(告警逻辑)
DeliverCallback callback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("[告警服务] 紧急! " + message);
};
channel.basicConsume(queueName, true, callback, consumerTag -> {});
}
}error日志会同时被「存储服务」和「告警服务」接收。

info和debug日志仅被「存储服务」接收。

路由模式是RabbitMQ中实现“精准消息投递”的核心方案,尤其适合需要按消息类型/级别差异化处理的场景(如日志分级、订单状态通知等)。掌握它的关键在于理解「Direct交换机+Routing Key+Binding Key」的三角关系——看似简单的机制,却能支撑起复杂业务的消息流转需求。
下次开发中遇到消息定向分发的需求,不妨试试RabbitMQ路由模式,让消息像被精准导航一样抵达目的地~
觉得有用请点赞收藏! 如果有相关问题,欢迎评论区留言讨论~