关于动态获取Topic交换机下所有队列的消息

小编今天主要讲的是RabbitMQ中的Topic模式

Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符!

Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert

通配符规则:

#:匹配一个或多个词

*:匹配不多不少恰好1个词

关于通配符的使用?

item.#:能够匹配item.spu.insert 或者 item.spu

item.*:只能匹配item.spu

在这里插入图片描述

解释:

  • Queue1:绑定的是china.# ,因此凡是以 china.开头的routing key 都会被匹配到。包括china.news和china.weather
  • Queue2:绑定的是#.news ,因此凡是以 .news结尾的 routing key 都会被匹配。包括china.news和japan.news

示例代码?

1.消息发送
在publisher服务的SpringAmqpTest类中添加测试方法:

/**
     * topicExchange
     */
@Test
public void testSendTopicExchange() {
    // 交换机名称
    String exchangeName = "itcast.topic";
    // 消息
    String message = "喜报!孙悟空大战哥斯拉,胜!";
    // 发送消息
    rabbitTemplate.convertAndSend(exchangeName, "china.news", message);
}

2.消息接收

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "topic.queue1"),
    exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),
    key = "china.#"
))
public void listenTopicQueue1(String msg){
    System.out.println("消费者接收到topic.queue1的消息:【" + msg + "】");
}

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "topic.queue2"),
    exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),
    key = "#.news"
))
public void listenTopicQueue2(String msg){
    System.out.println("消费者接收到topic.queue2的消息:【" + msg + "】");
}

如何动态获取所有队列?

其实RabbitMQ中一次性获取交换机下所有队列的信息的方法,最常用的无非就是Fanout模式 中文的理解意思又叫广播,我们可以声明式一个Fanout的交换机,然后另起一条队列fanoutQueue;将两者进行绑定,这样子fanoutQueue队列也能获取到Fanout交换机下发送给所有队列的每一个消息。

如果是项目中已经存在交换机了并且是Topic模式;然后交换机与队列之间绑定的routingKey没有使用通配符的形式。

在这里插入图片描述

关键点注意啦!!!

这种情况我们就可以合理使用通配符来解决我们动态获取所有队列的消息,#** 和 * ;当一个队列绑定键是#,那么这个队列将接收所有数据,就有点像 fanout 了,所以我们只需要另起一个队列绑定指定的交换机后将Routing Key 设置为 “#”就ok了。**

首先去生产者模块写一个测试类:

   @Test
    public void testFanoutExchange() {
        // 交换机名称
        String exchangeName = "robot.change";
        // 消息
        String message = "bug消失-bug消失-bug消失-bug消失-bug消失-bug消失";
        String message1 = "安静的做一个美男子就好了";
        String message2 = "未来几年希望程序员鼓励师这个岗位能够普遍实现";

        rabbitTemplate.convertAndSend(exchangeName, "autodoor", message);
        rabbitTemplate.convertAndSend(exchangeName, "lift", message1);
        rabbitTemplate.convertAndSend(exchangeName, "supply", message2);
    }

然后在我们的消费者端创建一个配置类,小编这里使用的是RabbitmMQ注解的方式声明交换机与队列的消息

@Configuration
@Slf4j
public class TopicConfig {

    @RabbitListener(bindings = @QueueBinding(value = @Queue(name = "api.queue"),
            exchange = @Exchange(name = "robot.change", type = ExchangeTypes.TOPIC),
            key = "#"))
    public void listenAPiQueue(String msgAll){
       System.out.println("获取到的所有队列消息如下:  " + msgAll);
    }
}

最后的结果就是这个 api.queue 队列获取到了交换机发给他底下所有队列的一个消息。

在这里插入图片描述

**希望上面的信息能够帮助到我们的每一个位小伙伴!!!
**
:Alt

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 是的,可以使用同样的路由键绑定到不同的队列。这样可以实现消息的多重路由,即将一条消息发送到多个队列中。当使用相同的路由键将消息发送到交换机时,交换机将会将消息复制到所有与该路由键匹配的队列中。这种方式可以用于实现负载均衡、消息广播等场景。但需要注意的是,这种方式可能会导致消息重复消费的问题,需要在消费者端进行处理。 ### 回答2: 可以使用相同的路由键绑定不同的队列。在消息队列中,交换机消息的分发中心,它根据消息的路由键将消息发送到相关的队列中。可以将多个队列绑定到同一个交换机,并使用相同的路由键进行绑定。这样,当有消息的路由键和交换机的绑定路由键匹配时,消息将被发送到所有与该交换机绑定的队列中。 使用相同的路由键绑定不同的队列有一些应用场景。一种情况是多个消费者对同一类消息进行处理,每个消费者使用一个队列进行消息的消费,通过使用相同的路由键绑定多个队列,可以实现消息的负载均衡。当有新的消息到达交换机时,交换机将根据路由键选择其中一个队列进行消息的投递,从而实现消息的分发。 另一种情况是不同的消费者对同一类消息进行不同的处理。每个消费者使用一个独立的队列进行消息的消费,使用相同的路由键绑定多个队列可以将消息按照不同的处理逻辑进行分发。例如,一个队列用于处理订单消息,另一个队列用于处理库存消息,使用相同的路由键绑定这两个队列可以实现将订单消息发送到订单队列,将库存消息发送到库存队列。 总之,使用相同的路由键绑定不同的队列可以实现消息的灵活分发,根据不同的应用场景和需求来确定使用哪种方式。 ### 回答3: 可以用相同的路由键绑定不同的队列。在使用交换机进行路由时,交换机会根据消息的路由键将消息发送到特定的队列中。当我们在绑定队列时,可以指定一个或多个路由键,交换机会将满足这些路由键的消息发送到相应的队列中。 因此,我们可以使用相同的路由键来绑定不同的队列,这意味着当消息的路由键与这些绑定的路由键相匹配时,消息将被发送到这些队列中。这种方式可以实现消息的多路由,即一条消息可以被发送到不同的队列中进行处理。 使用相同的路由键绑定不同的队列的一个常见应用场景是采用发布/订阅模式。在这种模式下,多个队列可以绑定到同一个交换机上,使用相同的路由键,这样交换机在接收到消息后会将消息发送到这些队列中,从而实现消息的多路复制。 当然,也可以根据实际需求使用不同的路由键绑定不同的队列。这样,消息会根据不同的路由键被发送到相应的队列中,实现消息的分类处理。 总之,交换机可以用相同的路由键绑定不同的队列,这种方式可以实现消息的多路由和分类处理,提供了灵活性和可扩展性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值