RabbitMQ入门:路由(Routing)

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

大家好,又见面了,我是全栈君。

在上一篇博客《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中我们就不能传入””了,需要指定具体的关键字。

    RabbitMQ入门:路由(Routing)

  2. binding key:

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

    RabbitMQ入门:路由(Routing)

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

RabbitMQ入门:路由(Routing)

二、多重绑定

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

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

RabbitMQ入门:路由(Routing)

 

三、代码实例

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

  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) {
                    @Override
                    public 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管理页面RabbitMQ入门:路由(Routing)

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

    有4个绑定关系,其中三个的队列是同一个。切换到Queues标签页:RabbitMQ入门:路由(Routing)

    有两个临时队列。

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120896.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • STM32毕业设计_stm32优秀毕业设计

    STM32毕业设计_stm32优秀毕业设计STM32毕业设计项目文章目录STM32毕业设计项目1、基于STM32单片机大棚环境参数无线蓝牙检测设计1、基于STM32单片机大棚环境参数无线蓝牙检测设计开题报告论文制作原理原理图&PCB

    2022年9月27日
    6
  • 河北2021文科一本分数线_19年文科二本分数线

    河北2021文科一本分数线_19年文科二本分数线2017年河北文科高考成绩排名一分一档表,河北高考文科成绩排名查询河北省共有40.48万人报名参加2017年高考,比2017年减少1.34万人,这已是河北省报考人数连续第七年下降。统计数据显示,统考报名人数为37.82万人,比2017年减少1.45万人;对口高考2.28万人,与2013年基本持平;只参加各种单独招生的近3800人,比2017年增加近1200人。报名考生中,应届考生34.73万人,社…

    2025年11月10日
    3
  • Jlink或者stlink用于SWD接口下载程序

    Jlink或者stlink用于SWD接口下载程序最近要使用stm32f103c8t6最小系统板,直接ISP串口下载程序太麻烦,就想着使用swd接口来调试。结果:通过SWD接口下载程序成功,但调试失败,还不知原因,会的的人麻烦交流一下。SWD接口:3.3VDIO(数据)CLK(时钟)GND1.首先声明jlink和stlink都有jtag和swd调试功能。jlink接口如下:如图,我使用的就是VCC…

    2022年4月25日
    53
  • 实验室仪器管理系统_实验室设备管理系统代码

    实验室仪器管理系统_实验室设备管理系统代码实验室设备管理系统主要包括:实验室设备信息的管理模块,实验室设备信息的浏览查询模块,设备事故记录模块,设备资料管理模块设备的损坏管理模块,设备损坏信息浏览查询,设备类别设置,系统用户的管理。通过本系统,可以更加有效的管理学生实验室设备信息开发技术:php,mysql,apache课题名称:实验室设备管理系统1)系统简介每学年要对实验室设备使用情况进行统计、更新。其中:(1)对于已彻底损坏的做报废处理,同时详细记录有关信息。(2)对于由严重问题(故障)的要及时修理,并记录修理日期、设备名、编号

    2022年10月13日
    4
  • linux安装weget命令,linux安装wget命令

    linux安装weget命令,linux安装wget命令wget命令是linux系统下的一个常用命令。下面由学习啦小编为大家整理了linux安装wget命令的相关知识,希望大家喜欢!linux安装wget命令方法一debian或者ubuntu:sudoapt-getinstallwgetcentos:sudoyum-yinstallwgetlinux安装wget命令方法二我们先安装linux系统比如centos7.1里面有的就…

    2022年10月16日
    3
  • 7个最优秀的手机游戏引擎

    7个最优秀的手机游戏引擎随着智能手机成为主要的游戏平台,移动游戏引擎变得越来越流行。下面将介绍7个最优秀的手机游戏引擎。1.CoronaSDK游戏开发引擎这是一款实用Lua语言作为开发语言的游戏引擎,对我来说比起的其他的游戏引擎要好学一点。而且,Lua语言现在很有游戏开发都有相关的支持。Coronasdk官方网址:https://coronalabs.com/Lua学习网址,最好从菜鸟教程开始http://www.runoob.com/lua/lua-tutorial.htmlCoronaSDK开发欢迎W

    2022年6月6日
    60

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号