RabbitMQ入门:主题路由器(Topic Exchange)[通俗易懂]

上一篇博文中,我们使用directexchange代替了fanoutexchange,这次我们来看下topicexchange。一、TopicExchange介绍topicexchan

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

上一篇博文中,我们使用direct exchange 代替了fanout exchange,这次我们来看下topic exchange。

一、Topic Exchange介绍

topic exchange和direct exchange类似,都是通过routing key和binding key进行匹配,不同的是topic exchange可以为routing key设置多重标准。

direct路由器类似于sql语句中的精确查询;topic 路由器有点类似于sql语句中的模糊查询。

还记得吗?我们在《RabbitMQ入门:发布/订阅(Publish/Subscribe)》中对exchange的分类进行过介绍:

Direct:完全根据key进行投递的,例如,绑定时设置了routing key为”abc”,那么客户端提交的消息,只有设置了key为”abc”的才会投递到队列。
Topic:对key进行模式匹配后进行投递,符号”#”匹配一个或多个词,符号”*”匹配正好一个词。例如”abc.#”匹配”abc.def.ghi”,”abc.*”只匹配”abc.def”。
Fanout:不需要key,它采取广播模式,一个消息进来时,投递到与该交换机绑定的所有队列。
Headers:我们可以不考虑它。

下面是官网给出的工作模型(P代表生产者,X代表exhange,红色的Q代表队列,C代表消费者):

RabbitMQ入门:主题路由器(Topic Exchange)[通俗易懂]

我们来分析下这个模型。

它发送的消息是用来描述动物的。路由键有三个单词:<speed>.<color>.<species>,第一个单词描述了速度,第二个描述了颜色,第三个描述了物种。
有三个绑定键,Q1绑定键为*.orange.*(关注所有颜色为orange的动物); Q2的绑定键有两个,分别是*.*.rabbit(关注所有的兔子)和lazy.#(关注所有速度为lazy的动物)。

因此,路由键为quick.orange.rabbit的消息将发送到Q1和Q2,路由键为quick.orange.fox的消息将发送到Q1,路由键为lazy.brown.fox的消息将发送到Q2。路由键为lazy.pink.rabbit的消息将发送到Q2,但是注意,它只会到达Q2一次,尽管它匹配了两个绑定键。路由键为quick.brown.fox的消息因为不和任意的绑定键匹配,所以将会被丢弃。

如果有人手一抖发了个lazy.orange.male.rabbit这种四个单词的,这个怎么办呢? 由于它和lazy.#匹配,因此将发送到Q2。

二、代码示例

接下来我们看下代码

  1. 生产者
    public class LogTopicSender {
        // exchange名字
        public static String EXCHANGE_NAME = "topicExchange";
    
        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.为通道声明topic类型的exchange
                channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
                
                // 3.发送消息到指定的exchange,队列指定为空,由exchange根据情况判断需要发送到哪些队列
                String routingKey = "info";
    //            String routingKey = "log4j.error";
    //            String routingKey = "logback.error";
    //            String routingKey = "log4j.warn";
                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 (connection != null) {
                    try {
                        connection.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }

     

  2. 消费者
    public class LogTopicReciver {
    
        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.为通道声明topic类型的exchange
                channel.exchangeDeclare(LogTopicSender.EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
                // 3.创建随机名字的队列
                String queueName = channel.queueDeclare().getQueue();
    
                // 4.建立exchange和队列的绑定关系
                String[] bindingKeys = { "#" };
    //            String[] bindingKeys = { "log4j.*", "#.error" };
    //            String[] bindingKeys = { "*.error" };
    //            String[] bindingKeys = { "log4j.warn" };
                for (int i = 0; i < bindingKeys.length; i++) {
                    channel.queueBind(queueName, LogTopicSender.EXCHANGE_NAME, bindingKeys[i]);
                    System.out.println(" **** LogTopicReciver 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("*********** LogTopicReciver" + " get message :[" + msg + "]");
                    }
                };
                // 6.消费消息
                channel.basicConsume(queueName, true, consumer);
    
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        }
    }

     

  3. 启动消费者,作为消费者1
  4. 分别将String[] bindingKeys = { “#” };改为String[] bindingKeys = { “log4j.*”, “#.error” };/String[] bindingKeys = { “*.error” };/String[] bindingKeys = { “log4j.warn” };,然后启动作为消费者2、消费者3、消费者4
  5. 启动4次生产者,routing key分别为String routingKey = “info”;、String routingKey = “log4j.error”;、String routingKey = “logback.error”;、String routingKey = “log4j.warn”;
  6. 观察控制台log
    生产者:
    product send a msg:  hello rabbitmq, I am info
    product send a msg:  hello rabbitmq, I am log4j.error
    product send a msg:  hello rabbitmq, I am logback.error
    product send a msg:  hello rabbitmq, I am log4j.warn
    
    消费者1:
     **** LogTopicReciver keep alive ,waiting for #
    *********** LogTopicReciver get message :[ hello rabbitmq, I am info]
    *********** LogTopicReciver get message :[ hello rabbitmq, I am log4j.error]
    *********** LogTopicReciver get message :[ hello rabbitmq, I am logback.error]
    *********** LogTopicReciver get message :[ hello rabbitmq, I am log4j.warn]
    
    消费者2:
     **** LogTopicReciver keep alive ,waiting for log4j.*
     **** LogTopicReciver keep alive ,waiting for #.error
    *********** LogTopicReciver get message :[ hello rabbitmq, I am log4j.error]
    *********** LogTopicReciver get message :[ hello rabbitmq, I am logback.error]
    *********** LogTopicReciver get message :[ hello rabbitmq, I am log4j.warn] 消费者3: **** LogTopicReciver keep alive ,waiting for *.error *********** LogTopicReciver get message :[ hello rabbitmq, I am log4j.error] *********** LogTopicReciver get message :[ hello rabbitmq, I am logback.error] 消费者4: **** LogTopicReciver keep alive ,waiting for log4j.warn *********** LogTopicReciver get message :[ hello rabbitmq, I am log4j.warn]

     

  7. 观察RabbitMQ管理页面RabbitMQ入门:主题路由器(Topic Exchange)[通俗易懂]

    RabbitMQ入门:主题路由器(Topic Exchange)[通俗易懂]

    RabbitMQ入门:主题路由器(Topic Exchange)[通俗易懂]

     

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

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

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


相关推荐

  • 根文件系统使用登录模式「建议收藏」

    根文件系统使用登录模式

    2022年1月30日
    48
  • 关于秒的单位_时间分秒后面是什么单位

    关于秒的单位_时间分秒后面是什么单位github地址秒的各单位换算1秒(s)=1000毫秒(ms)=1,000,000微秒(μs)=1,000,000,000纳秒(ns)=1,000,000,000,000皮秒(ps)=1,000,000,000,000,000飞秒(fs)=1,000,000,000,000,000,000渺秒(as)皮秒(英语:picosecond)天文学名词;符…

    2022年9月6日
    3
  • sae wpa3加密方式_WPA3:四大安全新特性技术分析

    sae wpa3加密方式_WPA3:四大安全新特性技术分析周一晚些时候,包括苹果、思科、英特尔、高通和微软等科技巨头在内的Wi-Fi联盟正式推出了新的Wi-Fi安全标准WPA3。这个标准将解决所有已知的、会影响重要标准的安全问题,同时还针对KRACK和DEAUTH等无线攻击给出缓解措施。WPA3为支持Wi-Fi的设备带来重要改进,旨在增强配置、加强身份验证和加密等问题。重要改进主要包括:防范暴力攻击、WAP3正向保密、加强公共和…

    2022年5月24日
    47
  • 2019最新PHP模拟面试题及答案「建议收藏」

    2019最新PHP模拟面试题及答案「建议收藏」PHP模拟面试题汇总如下:1.如何防止form表单重复提交?2.Cookie被禁用了session还可以使用吗?3.你了解的或者用过的版本控制工具有哪些?简单说明一下。CVS,SVN,vss,git4.单例模式的优点,如何实现?5.单引号和双引号的区别是什么?(1)双引号可以解析变量,单引号不能解析变量(2)双引号和单引号可以互相嵌套(3)双引号当中的变量可以使用特殊字符分隔…

    2022年8月27日
    2
  • Vue下路由History mode导致页面无法渲染的原因

    Vue下路由History mode导致页面无法渲染的原因

    2021年10月13日
    43
  • ftp文件下载工具,三个非常好使的ftp文件下载工具

    ftp文件下载工具,三个非常好使的ftp文件下载工具ftp文件下载工具是什么工具,可能有人会回答说不知道,因为一般只有从事网站管理的工作者会使用的多一点。但不是每个人生来就会的,所以刚开始肯定都会学习怎么使用。这篇文章就来告诉大家有哪些ftp文件下载工具吧。第一款:IIS7服务器管理工具说实话,这个工具算是比较好的管理工具了。里面的功能除了批量管理,还有很多别的功能,主要也是功能也比较全面,相信大多数使用的网站工作人员都比较熟悉了。它里面还能够定时上传下载、定时备份和主动更新。把你花在更新上的经历都省了。IIS7服务器管理工具除了在ftp上面有这么多的

    2022年6月5日
    67

发表回复

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

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