在上一篇博客《RabbitMQ入门:发布/订阅(Publish/Subscribe)》中,我们认识了fanout类型的exchange,它是一种通过广播方式发送消息的路由器,所有和exchange建立的绑定关系的队列都会接收到消息。但是有一些场景只需要订阅到一部分消息,这个时候就不能使用fanout 类型的exchange了,这个就引出来今天的“猪脚”--Direct Exchange,通过Routing Key来决定需要将消息发送到哪个或者哪些队列中。

接下来请收看详细内容:

  1. Direct Exchange(直接路由器)
  2. 多重绑定
  3. 代码实例

一、Direct Exchange(直接路由器)

在上文中介绍exchange的时候,对direct exchange进行了简单介绍,它是一种完全按照routing key(路由关键字)进行投递的:当消息中的routing key和队列中的binding key完全匹配时,才进行会将消息投递到该队列中。这里提到了一个routing key和binding key(绑定关键字),是什么东东?

  1. routing key:

    发送消息的时候,basicPublish的第二个参数就是routing key,由于上次是fanout 类型的exchange 进行广播方式投递,这个字段不会影响投递结果,因此我们这里就传入了“”,但是在direct 类型的exchange中我们就不能传入""了,需要指定具体的关键字。

  2. binding key:

    我们在前文中建立绑定关系的时候,queueBind的第三个参数就是绑定关键字

我们声明direact exchange的时候使用:

二、多重绑定

多个队列相同的绑定键绑定到同一个路由器的情况,我们称之为多重绑定

工作模型为(P代表生产者,X代表路由器,红色的Q代表队列,C代表消费者):

三、代码实例

预备知识了解完了,现在来写个程序感受下。

  1. 生产者

    public class LogDirectSender {// exchange名字public static String EXCHANGE_NAME = "directExchange";public static void main(String[] args) {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = null;Channel channel = null;try {// 1.创建连接和通道connection = factory.newConnection();channel = connection.createChannel();// 2.为通道声明direct类型的exchange
                channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);// 3.发送消息到指定的exchange,队列指定为空,由exchange根据情况判断需要发送到哪些队列String routingKey = "debug";String msg = " hello rabbitmq, I am " + routingKey;channel.basicPublish(EXCHANGE_NAME, routingKey, null, msg.getBytes());System.out.println("product send a msg: " + msg);} catch (IOException e) {e.printStackTrace();} catch (TimeoutException e) {e.printStackTrace();} finally {// 4.关闭连接if (channel != null) {try {channel.close();} catch (IOException e) {e.printStackTrace();} catch (TimeoutException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (IOException e) {e.printStackTrace();}}}}
    }

    和上次博客中生产者的区别就是黑字粗体部分:1.路由器类型改为direct 2.消息发布的时候指定了routing key

  2. 消费者
    public class LogDirectReciver {public static void main(String[] args) {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = null;Channel channel = null;try {// 1.创建连接和通道connection = factory.newConnection();channel = connection.createChannel();// 2.为通道声明direct类型的exchange
                channel.exchangeDeclare(LogDirectSender.EXCHANGE_NAME, BuiltinExchangeType.DIRECT);// 3.创建随机名字的队列String queueName = channel.queueDeclare().getQueue();// 4.建立exchange和队列的绑定关系String[] bindingKeys = { "error", "info", "debug" };
    //            String[] bindingKeys = { "error" };for (int i = 0; i < bindingKeys.length; i++) {channel.queueBind(queueName, LogDirectSender.EXCHANGE_NAME, bindingKeys[i]);System.out.println(" **** LogDirectReciver keep alive ,waiting for " + bindingKeys[i]);}// 5.通过回调生成消费者并进行监听Consumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope,com.rabbitmq.client.AMQP.BasicProperties properties, byte[] body) throws IOException {// 获取消息内容然后处理String msg = new String(body, "UTF-8");System.out.println("*********** LogDirectReciver" + " get message :[" + msg + "]");}};// 6.消费消息channel.basicConsume(queueName, true, consumer);} catch (IOException e) {e.printStackTrace();} catch (TimeoutException e) {e.printStackTrace();}}}

    和上次博客中消费者的区别就是黑字粗体部分:1.路由器类型改为direct 2.建立绑定关系的时候指定了binding key

  3. 执行消费者,控制台log打印如下:
     **** LogDirectReciver keep alive ,waiting for error**** LogDirectReciver keep alive ,waiting for info**** LogDirectReciver keep alive ,waiting for debug

    这个消费者我们视为消费者1,它会接收error,info,debug三个关键字的消息。

  4. 将String[] bindingKeys = { "error", "info", "debug" };改为String[] bindingKeys = { "error" };,然后再运行一次消费者。控制台log打印如下:
     **** LogDirectReciver keep alive ,waiting for error

    这个消费者我们视为消费者2,它只会接收error 关键字的消息。

  5. 执行生产者,然后将String routingKey = "debug";的值分别改为“info"和"error",然后分别执行,这样一共执行了三次生产者
    第一次执行:
    product send a msg:  hello rabbitmq, I am debug第二次执行:
    product send a msg:  hello rabbitmq, I am info第三次执行:
    product send a msg:  hello rabbitmq, I am error

  6. 再次查看两个消费者的控制台log:
    消费者1:**** LogDirectReciver keep alive ,waiting for error**** LogDirectReciver keep alive ,waiting for info**** LogDirectReciver keep alive ,waiting for debug
    *********** LogDirectReciver get message :[ hello rabbitmq, I am debug]
    *********** LogDirectReciver get message :[ hello rabbitmq, I am info]
    *********** LogDirectReciver get message :[ hello rabbitmq, I am error]消费者2:**** LogDirectReciver keep alive ,waiting for error
    *********** LogDirectReciver get message :[ hello rabbitmq, I am error]

  7. 查看RabbitMQ管理页面

    exchanges标签页里面多了个direct类型的路由器。进入详细页面:

    有4个绑定关系,其中三个的队列是同一个。切换到Queues标签页:

    有两个临时队列。

  8. 如果关掉消费者1和消费者2,会发现队列自动删除了,绑定关系也不存在了。

转载于:https://www.cnblogs.com/sam-uncle/p/9209666.html

RabbitMQ入门:路由(Routing)相关推荐

  1. RabbitMQ入门到进阶

    1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...

  2. RabbitMQ入门到进阶(Spring整合RabbitMQSpringBoot整合RabbitMQ)

    1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. ​ 编辑切换为居中 添加图片注释,不超过 140 字(可选) 2.为什么要 ...

  3. java 路由_RabbitMQ入门:路由(Routing)

    在上一篇博客<RabbitMQ入门:发布/订阅(Publish/Subscribe)>中,我们认识了fanout类型的exchange,它是一种通过广播方式发送消息的路由器,所有和exch ...

  4. RabbitMQ入门教程(安装,管理插件,Publisher/Consumer/交换机/路由/队列/绑定关系,及如何保证100%投递等)

    RabbitMQ入门教程(安装,管理插件,Publisher/Consumer/交换机/路由/队列/绑定关系,及如何保证100%投递等) 1. RabbitMQ简介及AMQP协议 开源的消息代理和队列 ...

  5. RabbitMQ入门到精通

    RabbitMQ 1. 消息中间件概述 1.1. 为什么学习消息队列 电子商务应用中,经常需要对庞大的海量数据进行监控,随着网络技术和软件开发技术的不断提高,在实战开发中MQ的使用与日俱增,特别是Ra ...

  6. rabbitmq入门(四)Topics主题模式

    文章目录 Topics主题模式 代码实现 测试 总结 下一章 Topics主题模式 交换机类型为 topics - 将路由和某个模式匹配,# 匹配一个或者多个,* 匹配一个.例如交换机绑定的routi ...

  7. RabbitMQ入门及笔记

    RabbitMQ 文章目录 RabbitMQ 1. RabbitMQ的安装 2. RabbitMQ的相关概念 2.1 RabbitMQ的概念 2.2 四大核心概念 2.3 RabbitMQ 核心部分 ...

  8. RabbitMQ入门到掌握

    RabbitMQ入门到掌握 一.消息队列 1.MQ 的相关概念 1.2 什么是MQ 1.2 为什么要用MQ ①流量消峰 ②应用解耦 ③异步处理 1.3 MQ 的分类 ①ActiveMQ ②Kafka ...

  9. 超详细的RabbitMQ入门

    转载:超详细的RabbitMQ入门,看这篇就够了!-阿里云开发者社区 思维导图 一.什么是消息队列 消息指的是两个应用间传递的数据.数据的类型有很多种形式,可能只包含文本字符串,也可能包含嵌入对象. ...

最新文章

  1. 消费者关注的 Win8 问题汇总(下)
  2. 甘特图 知乎_安利!拥有这5款甘特图工具,项目管理、生产排程轻松搞定!
  3. matlab-JDBC操作MYSQL数据库中文乱码解决
  4. scrapy拒绝访问
  5. 【BZOJ】2655: calc 动态规划+拉格朗日插值
  6. 中小企业SaaS型软件BI的发展前景
  7. 使用React和Tailwind CSS搭建项目框架
  8. APICloud学习笔记之窗体跳转
  9. pythonweb项目面试题_python和web框架面试题目整理(1)
  10. 14.go build
  11. dockerfile安装jenkins 并配置构建工具(node、npm、maven、git)
  12. Java 垃圾回收机制(GC)简述
  13. rpg人物制作软件_RPG游戏制作教程
  14. qpython 3h下载_QPython 3Hv3.0.0 Android
  15. 计算机桌面的字有毛边,windows系统屏幕显示的字体发虚有锯齿
  16. GALGAME文字提取agth v2008.11.20汉化版
  17. 超级表格企业版:服务上万家中小企业,提升效率
  18. mysql 正击剑_学正小学击剑课程彰显“亮剑”精神
  19. 模仿斗地主玩法实现扑克牌的分发
  20. 机器人RobotCali数据集解读

热门文章

  1. 【设计模式】适配器模式 Adapter Pattern
  2. Linux Shell基础 - Shell 脚本的执行方式
  3. JVM笔记(一)数字在JVM中的表示
  4. VB6 如何连接MYSQL数据库
  5. android.mk简单介绍
  6. Jquery Ajax +.ashx XML数据格式
  7. (53)FPGA面试题-利用任务task实现单字节乘法功能(Verilog语言实现)
  8. (21)Verilog HDL结构:task语句
  9. FPGA常用单位换算
  10. linux树形看磁盘,2 - 3、Linux—磁盘分区和挂载【2021-3-3】