6.RabbitMQ系列之direct直连交换器

我们通过fanout exchange(扇型交换机)实现生产者发送一个消息,这个消息同时被传送给所有队列。但是有时我们不希望所有的消息都被所有队列接收,我们希望可以指定类型为a的消息只能被队列A接收,类型为b的消息只能被队列B,C接收。扇型交换机只能无脑地广播消息给所有的消费者,其实质是广播给所有关联的队列

为了实现这个功能,一种是建立多个交换机,这种方式简单暴力但是不灵活。本节我们介绍使用单个直连交换机+路由实现以上功能

1. 单个绑定

1

在上图中,有2个队列绑定到直连交换机上。队列Q1使用绑定值为orange,队列Q2绑定值为black,green。在这种情况下,如果生产者发送的消息的路由值为orange,则此消息会被路由到队列Q1。如果生产者发送的消息的路由值为blcak,green,则此消息会被路由到队列Q2。其它的消息会被丢弃

2. 多个绑定

2

我们也可以将相同的绑定值绑定到不同的队列中。如上图中,队列Q1和Q2使用的绑定值都black。如果生产者发送的消息的路由值为black,则此消息会被同时路由到队列Q1和队列Q2

3. 完整代码示例
  • 新增DirectExchangeConfig.java
@Configuration
public class DirectExchangeConfig {

    @Bean
    public DirectExchange direct() {
        return new DirectExchange("direct");
    }

    private static class ConsumerConfig {

        @Bean
        public Queue directAutoDeleteQueue1() {
            return new AnonymousQueue();
        }

        @Bean
        public Queue directAutoDeleteQueue2() {
            return new AnonymousQueue();
        }

        @Bean
        public Binding directBinding1(DirectExchange direct, Queue directAutoDeleteQueue1) {
            return BindingBuilder.bind(directAutoDeleteQueue1).to(direct).with("orange");
        }

        @Bean
        public Binding directBinding2(DirectExchange direct, Queue directAutoDeleteQueue2) {
            return BindingBuilder.bind(directAutoDeleteQueue2).to(direct).with("black");
        }

        @Bean
        public Binding directBinding3(DirectExchange direct, Queue directAutoDeleteQueue2) {
            return BindingBuilder.bind(directAutoDeleteQueue2).to(direct).with("green");
        }
    }
}
  • 生产者
@Component
public class DirectSender {

    private RabbitTemplate rabbitTemplate;

    public DirectSender(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    public void send() {
        rabbitTemplate.convertAndSend("direct", "orange", "orange msg");
        rabbitTemplate.convertAndSend("direct", "green", "green msg");
        rabbitTemplate.convertAndSend("direct", "black", "black msg");
    }
}
  • 消费者
@Component
public class DirectReceiver {

    @RabbitListener(queues = "#{directAutoDeleteQueue1.name}")
    public void receive1(String in) {
        System.out.println("临时队列1接收到消息:" + in);
    }

    @RabbitListener(queues = "#{directAutoDeleteQueue2.name}")
    public void receive2(String in) {
        System.out.println("临时队列2接收到消息:" + in);
    }
}
  • 验证
@SpringBootTest
public class RabbitTest {

    @Autowired
    private DirectSender directSender;

    @Test
    public void testDirectSender() {
        directSender.send();
    }
}

2

可以看到绑定路由键black与green的队列2接收到消息

欢迎关注公众号算法小生沈健的技术博客

posted @ 2022-10-15 19:46  算法小生  阅读(39)  评论(0编辑  收藏  举报