rabbitmq通常意义上的广播实现

问题

最近在写一个功能的时候,由于某些资源需要分布式下每个服务都要执行一次,自然而然就想到了将资源广播出来。由于项目中已经集成了RabbitMq,本以为一个很简单的问题,结果出现了一些与平常想法不一样的问题

消息的交换器类型以及问题缘由

我们知道RabbitMq的交换器模式一共分为三种,分别时direct, topic, fanout, 通过routeKey将消息路由到绑定到对应交换器的队列上,我们现在要实现广播模式,就直接定义一个为fanout类型的交换器,由于fanout模式的路由键无意义,因此我们广播消息的时候直接向这个交换器直接发送消息即可。可问题在于,我定义了一个队列绑定到该交换器上时,最终消息消费时发现并没有如预期的那样,消息被每台机器都消费了,而是无论如何消息只会被某个服务实例消息一次,哎,真让人头大

问题解决

感觉RabbitMq这个消息中间件,先从概念上让接触消息中间件的人先晕乎一阵子,等慢慢的适应了交换器的概念之后,习惯性的将消息发到交换器然后消费时只关注队列的时候,这个时候广播的实现又把使用者按在地上再摩擦一顿!经过一番测试,得出一个结论,队列中的消息无论如何都会保证只被消费一次,无论你是点对点,还是广播都无法跳出这个定律。但是我现在就想实现广播应该怎么办呢?就是只关注交换器,除了路由键本身就是无效我们不关心以外,队列这个东西我们也不能关心。其实就是消费的时候只指定交换器的名称和交换器的类型为fanout,然后指定队列名为空串,即不指定定队列即可,让消费者自己去产生队列名称。这样消息产生的时候,广播的交换器有几个消费者就会产生几个队列名称。代码如下。

@RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "", durable = "true", autoDelete = "false"),
            exchange = @Exchange(value = BindingConst.ExchangeName.WS_PROMISE_FANOUT,type = ExchangeTypes.FANOUT)
    ))

队列名的效果就是下面这个样子滴
在这里插入图片描述

你可能感兴趣的:(rabbitmq)