RabbitMQ 六种基本队列模式 ----- 路由(routing)
在之前的消息 订阅/发布 模式中已经实现了通过 Fanout 来向所有的接受者广播,在 routing 中就是在 订阅/发布 中增加指定发送的 routing key 即可。下面的图也来自于官方的实例,Q1 和 Q2 绑定到了 X 的交换机上边,Q1 绑定了 orage 的 routing key ,Q2 绑定了 black 和 green 两个 routing key。这样在 p 使用 routing key 为 orange 发送时只有 Q1 会接收到消息。Q2 会将此消息抛弃。
使用 Java 来实现 发送者 和 接收者
-
第一步当然还是导入 Maven 坐标。
<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client --> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.9.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.25</version> <!-- <scope>test</scope>--> </dependency>
-
创建发送者端
private static final String EXCHANGE_NAME = "logs_routing"; public static void main(String[] args) { try { ConnectionFactory factory = new ConnectionFactory(); // 设置参数 factory.setHost("192.168.3.64"); factory.setPort(5672); factory.setVirtualHost("/default_virtual_host"); factory.setUsername("admin"); factory.setPassword("admin"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); // 创建交换机 此处不能用 FANOUT 作为交换机的类型了 ,需要换成 DIRECT channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, true, false, false, null); // 声明两个队列 channel.queueDeclare("log_fanout_queue1", false, false, false, null); channel.queueDeclare("log_fanout_queue2", false, false, false, null); // 绑定两个队列 (此处必须要要指定 routingkey) // 队列1只接收 info channel.queueBind("log_fanout_queue1", EXCHANGE_NAME, "info"); // 队列2接收所有 channel.queueBind("log_fanout_queue2", EXCHANGE_NAME, "info"); channel.queueBind("log_fanout_queue2", EXCHANGE_NAME, "warn"); channel.queueBind("log_fanout_queue2", EXCHANGE_NAME, "error"); String message = "[日志][支付信息][订单号:" + new Date().getTime() + "][支付ID:10]"; // 由于要使用 routing 模式发送所以就需要执行 routingkey channel.basicPublish(EXCHANGE_NAME, "info", null, message.getBytes(StandardCharsets.UTF_8)); channel.basicPublish(EXCHANGE_NAME, "error", null, message.getBytes(StandardCharsets.UTF_8)); // 释放资源 channel.close(); connection.close(); } catch (IOException | TimeoutException e) { e.printStackTrace(); } }
-
创建第一个接受者
private static final String EXCHANGE_NAME = "logs_routing"; public static void main(String[] args) { try { ConnectionFactory factory = new ConnectionFactory(); // 设置参数 factory.setHost("192.168.3.64"); factory.setPort(5672); factory.setVirtualHost("/default_virtual_host"); factory.setUsername("admin"); factory.setPassword("admin"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, true, false,false, null); String queue1Name = "log_direct_queue1"; DeliverCallback deliverCallback = (consumerTag, delivery) -> { String message = new String(delivery.getBody(), StandardCharsets.UTF_8); System.out.println(" [info] Received '" + message + "'"); }; channel.basicConsume(queue1Name, true, deliverCallback, consumerTag -> { }); } catch (IOException | TimeoutException e) { e.printStackTrace(); } }
-
创建第二个接受者
private static final String EXCHANGE_NAME = "logs_routing"; public static void main(String[] args) { try { ConnectionFactory factory = new ConnectionFactory(); // 设置参数 factory.setHost("192.168.3.64"); factory.setPort(5672); factory.setVirtualHost("/default_virtual_host"); factory.setUsername("admin"); factory.setPassword("admin"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, true, false,false, null); String queue1Name = "log_direct_queue2"; DeliverCallback deliverCallback = (consumerTag, delivery) -> { String message = new String(delivery.getBody(), StandardCharsets.UTF_8); System.out.println(" [info,error,warn] Received '" + message + "'"); }; channel.basicConsume(queue1Name, true, deliverCallback, consumerTag -> { }); } catch (IOException | TimeoutException e) { e.printStackTrace(); } }
在发送者发送消息到指定的队列这时候两个接受者返回的消息为
通过查看以上代码可以看出这个和 pub/sub 方式是一样,只不过是把广播模式切换成了指定方向的发送。然后在通道上绑定队列的时候要指定 routingKey 即可。
欢迎前往我的个人博客 www.runbrick.com,博客园同步更新。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?