rabbitmq多个消费者消费同一个队列中的同一条消息

前言

使用springboot整合rabbitmq实现,一个生产者生产一条数据,多个消费者消费同一条数据案例,可以解决微服务分布式事务控制。保证最终一致性原则

rabbitmq是什么?

相对简易得一种消息中间件,功能强大,性能中等,吞吐量一般。

使用步骤

  1. 引入库

    <!-- rabbitmq消息队列-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
    </dependency>
    
  2. rabbitmq相关配置

    @Configuration
    public class RabbitmqConfig {
    	@Bean
        public Queue queue1() {
            return new Queue("queue1",true);
        }
    
        @Bean
        public FanoutExchange exchange1() {
            return new FanoutExchange("exchange1",true, false);
        }
    
        @Bean
        public Binding binding1() {
            return BindingBuilder.bind(queue1()).to(exchange1());
        }
    }
    

    因为是fanout广播模式,所以不用配置路由键

  3. 生产者代码

    @Resource
    private RabbitTemplate rabbitTemplate;
    
    @Test
    public void pushMessage() {
        HashMap<Object, Object> hashMap = new HashMap<>();
        hashMap.put("name","zhangsan");
        hashMap.put("age","18");
        rabbitTemplate.convertAndSend("exchange1","", hashMap);
    }
    
  4. 多个消费者,消费同一条数据

    消费者1号

    @Component
    public class RabbitMqConsumer {
    //    @RabbitListener(queues = "queue1")
        @RabbitListener(bindings = @QueueBinding(
                // value = @Queue(value = "queue1"),
    		value = @Queue(), //切记: 此处无需设置队列名称,否在得话,多个消费者只有一个消费者能消费数据。其它消费者无法消费数据。
            exchange = @Exchange(value = "exchange1",type = ExchangeTypes.FANOUT)
        ))
        public void getData(Message message) {
            try {
                String str = new String(message.getBody(),"utf-8");
                System.out.println(str);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    消费者2号

    @Component
    public class RabbitMqConsumer {
    	// @RabbitListener(queues = "queue1")
        @RabbitListener(bindings = @QueueBinding(
    	// value = @Queue(value = "queue1"),
    		value = @Queue(), //切记: 此处无需设置队列名称,否在得话,多个消费者只有一个消费者能消费数据。其它消费者无法消费数据。
            exchange = @Exchange(value = "exchange1",type = ExchangeTypes.FANOUT)
        ))
        public void getData(Message message) {
            try {
                String str = new String(message.getBody(),"utf-8");
                System.out.println(str);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
RabbitMQ 同一个消息只能被一个消费者消费。如果多个消费者同时消费同一个队列消息,每个消息只会被其一个消费者消费。 如果需要多个消费者同时处理同一个消息,可以使用 RabbitMQ 的“发布/订阅”模式。在这种模式下,每个消费者都订阅一个自己的队列,并且这些队列都绑定到同一个交换机上。当一个生产者发送一条消息时,这条消息会被交换机广播到所有绑定的队列,每个消费者都会收到一份拷贝。 以下是使用 Python Pika 库实现多个消费者同时处理同一个消息的示例代码: ```python import pika import time # 连接 RabbitMQ 服务器 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # 创建一个名为 'my_exchange' 的交换机 channel.exchange_declare(exchange='my_exchange', exchange_type='fanout') # 创建一个名为 'my_queue' 的队列 channel.queue_declare(queue='my_queue') # 将 'my_queue' 队列绑定到 'my_exchange' 交换机 channel.queue_bind(queue='my_queue', exchange='my_exchange') # 定义回调函数用于处理收到的消息 def callback(ch, method, properties, body): print("Received %r" % body) time.sleep(1) # 模拟处理消息的耗时 print("Done") ch.basic_ack(delivery_tag=method.delivery_tag) # 设置每个消费者只处理一个消息 channel.basic_qos(prefetch_count=1) # 启动多个消费者同时消费 'my_queue' 队列消息 for i in range(3): # 创建一个名为 'consumer_queue_{i}' 的队列 queue_name = 'consumer_queue_%d' % i channel.queue_declare(queue=queue_name) # 将 'consumer_queue_{i}' 队列绑定到 'my_exchange' 交换机 channel.queue_bind(queue=queue_name, exchange='my_exchange') # 每个消费者消费自己的队列消息 channel.basic_consume(queue=queue_name, on_message_callback=callback) print('Waiting for messages. To exit press CTRL+C') channel.start_consuming() ``` 在上面的示例代码,我们创建了三个消费者,每个消费者都订阅一个自己的队列,并将这些队列绑定到同一个交换机 `my_exchange` 上。当一个生产者发送一条消息时,这条消息会被交换机广播到所有绑定的队列,每个消费者都会收到一份拷贝。在每个消息被处理完成后,调用 `ch.basic_ack(delivery_tag=method.delivery_tag)` 告诉 RabbitMQ消息已经被成功处理了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值