美文网首页
Spring Boot RabbitMQ 入门(四)之 Topi

Spring Boot RabbitMQ 入门(四)之 Topi

作者: 5d44bc28b93d | 来源:发表于2017-02-16 16:19 被阅读781次

0.回顾


Spring Boot RabbitMQ 入门(三)之 Fanout交换器
上篇文章我们学习了以下几点:

  • 1.如何创建消息生产者
  • 2.如何使用消息生产者发送消息
  • 3.如何定义Fanout交换器
  • 4.将对列绑定到交换器从而测试其特性

1.Topic交换器介绍


Topic.png
如上图所示
此类交换器使得来自不同的源头的消息可以到达一个对列,其实说的更明白一点就是模糊匹配的意思,例如:上图中红色对列的routekey为usa.#,#代表匹配任意字符,但是要想消息能到达此对列,usa.必须匹配后面的#好可以随意。图中usa.news usa.weather,都能找到红色队列,符号“#”匹配一个或多个词,符号“”匹配不多不少一个词。因此“usa.#”能够匹配到“usa.news.XXX”,但是“usa.” 只会匹配到“usa.XXX”。
注:
交换器说到底是一个名称与队列绑定的列表。当消息发布到交换器时,实际上是由你所连接的信道,将消息路由键同交换器上绑定的列表进行比较,最后路由消息

2.Topic交换器实践


2.1创建交换器


 @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange(EXCHANGE);
    }

2.2创建队并


 @Bean
    public Queue queue() {
        return new Queue("spring-queue", true); //队列持久
    }
    @Bean
    public Queue queue2() {
        return new Queue("spring-queue2", true); //队列持久
    }

2.3对列绑定并关联到ROUTINGKEY

此处要理解Topic交换器介绍中的注部分就明白
两个对列分别匹配两个不同规则

public static final String EXCHANGE   = "spring-topic-exchange";
    public static final String ROUTINGKEY1 = "weather-routingKey.*";
    public static final String ROUTINGKEY2 = "msg-routingKey.#";
    @Bean
    public Binding binding() {
        return BindingBuilder.bind(queue()).to(topicExchange()).with(ROUTINGKEY1);
    }
    @Bean
    public Binding binding2() {
        return BindingBuilder.bind(queue2()).to(topicExchange()).with(ROUTINGKEY2);
    }

2.4创建消费者,分别消费两对列


Bean
    public SimpleMessageListenerContainer messageContainer() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
        container.setQueues(queue());
        container.setExposeListenerChannel(true);
        container.setMaxConcurrentConsumers(1);
        container.setConcurrentConsumers(1);
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
        container.setMessageListener(new ChannelAwareMessageListener() {
            @Override
            public void onMessage(Message message, Channel channel) throws Exception {
                byte[] body = message.getBody();
                          System.out.println("receive msg queue: " + new String(body));
                          Thread.sleep(10000);

                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费

            }
        });
        return container;
    }

    @Bean
    public SimpleMessageListenerContainer messageContainer2() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
        container.setQueues(queue2());
        container.setExposeListenerChannel(true);
        container.setMaxConcurrentConsumers(1);
        container.setConcurrentConsumers(1);
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
        container.setMessageListener(new ChannelAwareMessageListener() {
            @Override
            public void onMessage(Message message, Channel channel) throws Exception {
                byte[] body = message.getBody();
                System.out.println("receive msg queue2: " + new String(body));
                Thread.sleep(10000);
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费


            }
        });
        return container;
    }

2.5消息生产者生产消息


@Autowired
    RabbitTemplate template;
    public void send(String context) {
        template.convertAndSend(RabbitConfig.EXCHANGE, "weather-routingKey.a", context);

    }

2.验证


此处为了方便验证就不采用发送者发送了,直接用RabbitMQ管理端进行发送

  • 1情况一
f.png

我们匹配对列2的msg-routingKey.#
输出结果如下
预计情况会queue2对列消费者消费消息

receive msg queue2: 21213
  • 2情况二
    我们前文讲到采用#可以匹配多个字符
    我们使用routingKey =msg-routingKey.a.b如果前文正确,则
    输出结果如下
receive msg queue2: msg-routingKey.a.b
  • 3.情况三
    *匹配只能是单个字符所以我们我们使用routingKey =weather-routingKey.a如果前文正确,则输出对列queue接受到消息
    结果如下:
receive msg queue: weather-routingKey.a
  • 4.情况四
    我们模拟*匹配“多个字符”的情况routingKey =weather-routingKey.a.b
    如果前文正确,则消息会进入消息"黑洞",被丢弃,没有输出。
    结果如下:
.

最后

注:此处的多个字符是指以"."间隔为一个。
Direct其实就是要求routingKey 完全匹配,所以就不再赘述

相关文章

网友评论

      本文标题:Spring Boot RabbitMQ 入门(四)之 Topi

      本文链接:https://www.haomeiwen.com/subject/yabcwttx.html