【RabbitMQ】基础四:路由模式(Routing)

  • 1. 路由模式说明
  • 2. 代码示例
    • 2.1 生产者
    • 2.2 消费者1
    • 2.3 消费者2
    • 2.4 测试
  • 3. 总结

1. 路由模式说明

路由模式特点:

  • 队列与交换机的绑定,不能是任意绑定了,而是要指定一个 RoutingKey (路由key)消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey 。
  • Exchange不再把消息交给每一个绑定的队列,而是根据消息的 Routing Key 进行判断,只有队列的Routingkey 与消息的 Routing key 完全一致,才会接收到消息。

图解:

P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。
X:Exchange(交换机),接收生产者的消息,然后把消息递交给 与routing key完全匹配的队列。
C1:消费者,其所在队列指定了需要routing key 为 error 的消息。
C2:消费者,其所在队列指定了需要routing key 为 info、error、warning 的消息。

2. 代码示例

导入依赖:

        <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.10.0</version></dependency>

在编码上与 Publish/Subscribe发布与订阅模式 的区别是交换机的类型为:Direct,还有队列绑定交换机的时候需要指定routing key。

2.1 生产者

package com.siyi.routing;import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;public class ConnectionUtil {public static Connection getConnection() throws Exception {//创建连接工厂ConnectionFactory connectionFactory = new ConnectionFactory();//设置主机地址;默认为localhostconnectionFactory.setHost("localhost");//连接端口;默认为 5672connectionFactory.setPort(5672);//虚拟主机名称;默认为/connectionFactory.setVirtualHost("/siyi");//连接用户名;默认为guestconnectionFactory.setUsername("siyi");//连接密码;默认为guestconnectionFactory.setPassword("siyi");//返回连接return connectionFactory.newConnection();}
}
package com.siyi.routing;import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;public class Producer {//交换机名称static final String DIRECT_EXCHANGE = "direct_exchange";//队列名称static final String DIRECT_QUEUE_INSERT = "direct_queue_insert";//队列名称static final String DIRECT_QUEUE_UPDATE = "direct_queue_update";public static void main(String[] args) throws Exception {//创建连接Connection connection = ConnectionUtil.getConnection();//创建频道Channel channel = connection.createChannel();/*** 声明交换机* 参数1:交换机名称* 参数2:交换机类型,fanout,toppic,direct,headers*/channel.exchangeDeclare(DIRECT_EXCHANGE, BuiltinExchangeType.DIRECT);//声明(创建)队列/*** 参数1:队列名称* 参数2:是否定义持久化队列* 参数3:是否独占本次连接* 参数4:是否在不使用的时候自动删除队列* 参数5:队列其它参数*/channel.queueDeclare(DIRECT_QUEUE_INSERT,true,false,false,null);channel.queueDeclare(DIRECT_QUEUE_UPDATE,true,false,false,null);//队列绑定交换机channel.queueBind(DIRECT_QUEUE_INSERT,DIRECT_EXCHANGE,"insert");channel.queueBind(DIRECT_QUEUE_UPDATE,DIRECT_EXCHANGE,"update");//发送消息String message = "新增了商品。路由模式:routing key 为 insert";/*** 参数1:交换机名称,如果没有指定则使用默认Default Exchage* 参数2:路由key,简单模式可以传递队列名称* 参数3:消息其它属性* 参数4:消息内容*/channel.basicPublish(DIRECT_EXCHANGE,"insert",null,message.getBytes());System.out.println("已发送消息:"+message);//发送消息message = "修改了商品。路由模式:routing key 为 update";/*** 参数1:交换机名称,如果没有指定则使用默认Default Exchage* 参数2:路由key,简单模式可以传递队列名称* 参数3:消息其它属性* 参数4:消息内容*/channel.basicPublish(DIRECT_EXCHANGE,"update",null,message.getBytes());System.out.println("已发送消息:"+message);//关闭资源channel.close();connection.close();}
}

2.2 消费者1

package com.siyi.routing;import com.rabbitmq.client.*;import java.io.IOException;public class Consumer1 {public static void main(String[] args) throws Exception {//创建连接Connection connection = ConnectionUtil.getConnection();//创建通道(频道)Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(Producer.DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);//声明(创建)队列/*** 参数1:队列名称* 参数2:是否定义持久化队列* 参数3:是否独占本次连接* 参数4:是否在不使用的时候自动删除队列* 参数5:队列其它参数*/channel.queueDeclare(Producer.DIRECT_QUEUE_INSERT,true,false,false,null);//队列绑定交换机channel.queueBind(Producer.DIRECT_QUEUE_INSERT, Producer.DIRECT_EXCHAGE,"insert");//创建消费这,并设置消息处理DefaultConsumer consumer = new DefaultConsumer(channel) {/*** consumerTag 消息者标签,在channel.basicConsume时候可以指定* envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,*          消息和重传标志(收到消息失败后是否需要重新发送)* properties 属性信息* body 消息*/@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {//路由keySystem.out.println("路由key为:" + envelope.getRoutingKey());//交换机System.out.println("交换机为:" + envelope.getExchange());//消息idSystem.out.println("消息id为:" + envelope.getDeliveryTag());//收到的消息System.out.println("消费者1-接收到的消息为:" + new String(body, "utf8"));}};//监听消息/*** 参数1:队列名称* 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认* 参数3:消息接收到后回调*/channel.basicConsume(Producer.DIRECT_QUEUE_INSERT, true, consumer);}
}

2.3 消费者2

package com.siyi.routing;import com.rabbitmq.client.*;import java.io.IOException;public class Consumer2 {public static void main(String[] args) throws Exception {//创建连接Connection connection = ConnectionUtil.getConnection();//创建通道(频道)Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(Producer.DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);//声明(创建)队列/*** 参数1:队列名称* 参数2:是否定义持久化队列* 参数3:是否独占本次连接* 参数4:是否在不使用的时候自动删除队列* 参数5:队列其它参数*/channel.queueDeclare(Producer.DIRECT_QUEUE_UPDATE,true,false,false,null);//队列绑定交换机channel.queueBind(Producer.DIRECT_QUEUE_UPDATE, Producer.DIRECT_EXCHAGE,"update");//创建消费这,并设置消息处理DefaultConsumer consumer = new DefaultConsumer(channel) {/*** consumerTag 消息者标签,在channel.basicConsume时候可以指定* envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,*          消息和重传标志(收到消息失败后是否需要重新发送)* properties 属性信息* body 消息*/@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {//路由keySystem.out.println("路由key为:" + envelope.getRoutingKey());//交换机System.out.println("交换机为:" + envelope.getExchange());//消息idSystem.out.println("消息id为:" + envelope.getDeliveryTag());//收到的消息System.out.println("消费者2-接收到的消息为:" + new String(body, "utf8"));}};//监听消息/*** 参数1:队列名称* 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认* 参数3:消息接收到后回调*/channel.basicConsume(Producer.DIRECT_QUEUE_UPDATE, true, consumer);}
}

2.4 测试

启动所有消费者,然后使用生产者发送消息;在消费者对应的控制台可以查看到生产者发送对应routing key对应队列的消息;到达按照需要接收的效果。

在执行完测试代码后,其实到RabbitMQ的管理后台找到 Exchanges 选项卡,点击 direct_exchange 的交换机,可以查看到如下的绑定:

先启动两个消费者,再启动生产者。
生产者运行结果:

消费者1运行结果:

消费者2运行结果:

3. 总结

Routing模式要求队列在绑定交换机时要指定routing key,消息会转发到符合routing key的队列。

【RabbitMQ】基础四:路由模式(Routing)相关推荐

  1. RabbitMQ学习(四) 订阅模式-Direct(直连)

    直连模式说明 在fanout模式中,一条消息,会被所有订阅的队列都消费,但是在某些场景下,我们希望不同的消息被不同的队列消费,这时就要用到Direct类型的Exchange. 使用说明 1.相较于fa ...

  2. RabbitMQ (四) 路由选择 (Routing)

    上一篇博客我们建立了一个简单的日志系统,我们能够广播日志消息给所有你的接收者,如果你不了解,请查看:RabbitMQ (三) 发布/订阅.本篇博客我们准备给日志系统添加新的特性,让日志接收者能够订阅部 ...

  3. RabbitMq | springboot (路由模式RoutingKey)整合Direct交换器

    生产者发送消息到交换机并指定一个路由key,消费者队列绑定到交换机时要制定路由key(key匹配就能接受消息,key不匹配就不能接受消息) 引入依赖: <dependency><gr ...

  4. RabbitMQ路由模式(direct)

    1.什么是路由模式(direct) 路由模式是在使用交换机的同时,生产者指定路由发送数据,消费者绑定路由接受数据.与发布/订阅模式不同的是,发布/订阅模式只要是绑定了交换机的队列都会收到生产者向交换机 ...

  5. RabbitMQ基础学习

    一.RabbitMQ介绍 MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协 ...

  6. java 模拟实现mq,RabbitMQ的5种模式,并使用java进行模拟操作

    2. RabbitMQ的5种工作模式 然后就开始记录一下学习到的吧!多多指教 2.1 简单模式 就是将一个生产者绑定到一个消息队列,然后消费者从这个消息队列中取消息进行消费 在生产者与队列之间,使用的 ...

  7. rabbitmq几种工作模式_RabbitMQ的六种工作模式总结

    精品推荐 国内稀缺优秀Java全栈课程-Vue+SpringBoot通讯录系统全新发布! 作者:侧身左睡 https://www.cnblogs.com/xyfer1018/p/11581511.ht ...

  8. 消息中间件的应用场景与 RabbitMQ的六种工作模式介绍

    消息中间件的应用场景与 RabbitMQ的六种工作模式介绍 消息中间件应用场景 异步处理 应用解耦 流量削峰 RabbitMQ的六种工作模式 简单模式 工作模式 发布订阅模式 路由模式 主题模式 PR ...

  9. 快速入门RabbitMQ(详细)第二篇:RabbitMQ五种工作模式的使用及总结

    4. RabbitMQ工作模式 4.1. Work queues工作队列模式 Work Queues 与入门程序的 简单模式 相比,多了一个或一些消费端,多个消费端共同消费同一个队列中的消息.应用场景 ...

最新文章

  1. Codeforces Round #645 (Div. 2)(D.The Best Vacation)
  2. 《iOS应用软件设计之道》—— 3.1 流向:从一个画面到另一个画面
  3. debian android环境搭建,Debian类系统环境变量的配置
  4. 每天一个linux命令(17):whereis 命令
  5. VS2005集成VSS2005的方法
  6. Android中使用File文件进行数据存储
  7. Apollo 刨析:简介
  8. ​Go 能取代 Java,成为下一个 10 年的王者吗?​
  9. 《大数据》致谢审稿专家
  10. 区间DP之环形石子合并
  11. go grpc压缩_跟我学 gRPC—1. gRPC 及相关介绍
  12. 根据某一字段值去重查找出所有字段的数据
  13. Vim 的几个彩蛋。。
  14. 通过ida dump Uinity3D的加密dll
  15. scala安装与配置
  16. 如何把epub转mobi?
  17. 手机怎么把照片转JPG格式?这三种手机小技巧需要知道
  18. 构词法重新辨析triweekly与entrance
  19. 约瑟夫环问题-以python为舟
  20. 《手把手教你学51单片机》之十三------1602液晶与串口的应用实例

热门文章

  1. Linux驱动开发---杂项设备
  2. Hinton最新演讲!一种新神经网络:前向-前向FF算法,论文已公开!
  3. VUE+audio实现前端消息提示音效
  4. 软件设计学习笔记1_架构
  5. 很多人都说flash as3 经常都是使用MC或者sprite(请问这里的sprite是什么意思?)...
  6. usart hmi(串口屏)常用命令
  7. 微博吃瓜总是晚一步才知道,程序员直接写了一个热搜提醒工具
  8. 网易前端JavaScript编码规范
  9. HTML中表格table边框border(1px还嫌粗)的解决方案:
  10. MySQL中 begin 事务 begin ,第二个begin带自动提交功能???