多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 1. 什么是重复消费 **1. 什么是重复消费** 重复消费是指:由同一个生产者生产的消息,所有的消费者接收到的消息都是一模一样的。 <br/> 为了方便演示消息被重复消费的效果,参考 cloud-stream-rabbitmq-consumer8802 消费者模块再构建一个 cloud-stream-rabbitmq-consumer8803 消费者模块,源码中已经提供。 <br/> 先启动 cloud-stream-rabbitmq-provider8801 生产者模块生产消息,然后分别启动 8802 消费者 和 8803 消费者。 <br/> 访问8801生产者生产消息:http://localhost:8801/sendMessage ``` 生产者:014c1223-fa7a-4df5-bd45-778097074a4c 生产者:d82097cd-d461-48b2-901a-399122e4469a 生产者:3f6ac994-7c33-46c1-bc8a-248eee8510e5 8802消费者:014c1223-fa7a-4df5-bd45-778097074a4c 8802消费者:d82097cd-d461-48b2-901a-399122e4469a 8802消费者:3f6ac994-7c33-46c1-bc8a-248eee8510e5 8803消费者:014c1223-fa7a-4df5-bd45-778097074a4c 8803消费者:d82097cd-d461-48b2-901a-399122e4469a 8803消费者:3f6ac994-7c33-46c1-bc8a-248eee8510e5 ``` 可见 8802 消费者 与 8803 消费者接收到的消息是一模一样的,这就是消息被重复消费的问题。 <br/> **2. 消费被重复消费的原因** 消息之所以被重复消费,是因为Stream定义不属于同一组的消费者是可以重复消费消息的。默认是不分组的。 <br/> **3. 为什么要避免重复消费** 在生产实际中,比如在如下场景中,订单系统我们做集群部署,都会从RabbitMQ中获取订单信息,那<mark>如果一个订单同时被两个服务获取到,那么就会造成数据错误,产生两次结账</mark>。我们得避免这种情况。这时我们就可以使用Stream中的<mark>消息分组</mark>来解决。 ![](https://img.kancloud.cn/bc/04/bc04682525a32132f388c826a83eaa5f_1102x402.jpg) 注意在Stream中<mark>处于同一个组中的多个消费者是竞争关系,就能够保证消息只会被其中一个应用消费一次。不同组是可以全面消费的(重复消费)</mark>。 <br/> # 2. 解决重复消费问题 <mark>处于同一个组中的多个消费者是竞争关系,就能够保证消息只会被其中一个应用消费一次。不同组是可以全面消费的(重复消费)</mark>。 <br/> 将 8802 消费者 和 8803 消费者 分在同一个组`group: atguiguA`内即可实现消息不被重复消费。 ``` #在两个消费端做如下配置 spring.cloud.stream.bindings.input.group: atguiguA #分组 ``` <br/> 访问8801生产者生产消息:http://localhost:8801/sendMessage ``` 生产者:c84ffd99-1f90-46ea-add6-ae36147e3f50 生产者:e525446e-3bf6-4efc-a0d9-30355261a1ff 生产者:fe83b854-50f7-4c43-9995-5f9aa5420621 生产者:fd6b30a9-f3da-4334-9fd9-c767a56ba1a4 生产者:84e232a9-49bd-4293-944f-5d2e11933e90 生产者:d9387e40-74f7-47a9-9965-12f30258701a 8802消费者:c84ffd99-1f90-46ea-add6-ae36147e3f50 8802消费者:fe83b854-50f7-4c43-9995-5f9aa5420621 8802消费者:84e232a9-49bd-4293-944f-5d2e11933e90 8803消费者:e525446e-3bf6-4efc-a0d9-30355261a1ff 8803消费者:fd6b30a9-f3da-4334-9fd9-c767a56ba1a4 8803消费者:d9387e40-74f7-47a9-9965-12f30258701a ``` 可见 8802 消费者 与 8803 消费者接收到的消息是完全不同的,这就解决了消息被重复消费的问题。