Rocketmq同项目多个生产者多个消费者问题

在使用RocketMQ进行多实例部署时,发现所有消息都发送到了同一MQ服务器。深入源码发现,由于未设置InstanceName,导致每次启动的客户端ID相同,所有实例共用同一MQClientInstance,从而消息误发至同一MQ。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中经常会遇到一个项目需要多个mq实例的情况,然后我们就启动了多个mq:

在这里插入图片描述

另一个也同样此种方法启动,@Bean对象的bean名称不一样。
但是用的时候发现无论用哪个生产者实例,发送的消息总是到同一个mq上。
在发送消息的时候加上断点,查看product对象,发现namesrvAddr是对的,不同的mq实例发送消息时namesrvAddr是不同的。
无可奈何之下,查看了下rocketmq的源码,发现在mq执行start时,会去取一个MQClientInstance实例
在这里插入图片描述
再进去就是:
在这里插入图片描述
它会去factoryTable(一个ConcurrentMap)取MQClientInstance,取的时候用的key时clientId,然后查看clientId时从clientConfig.buildMQClientId()方法获取的,进入clientConfig.buildMQClientId()方法:
在这里插入图片描述
发现client是由clientIp和InstanceName组成的,由于InstanceName没有设置,所以每次返回都是同一个clinetId,导致mq每次拿到的MQClientInstance都是同一个,都发送到了同一个mq服务端了。
调试时发现的mq的namesrvAddr变了只是DefaultMQProducer这个对象的namesrvAddr属性变了,没什么卵用。

### Spring Boot 集成 RocketMQ 实现多消费者和多生产者 #### 添加依赖项 为了在 Spring Boot 项目中集成 RocketMQ,需在 `pom.xml` 文件中添加 RocketMQ 的启动器依赖。版本号应根据实际需求选择稳定版。 ```xml <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> ``` 此操作确保了应用程序能够访问到必要的类库来完成消息队列的操作[^1]。 #### 生产者配置与实现 创建多个生产者实例可以通过定义不名称的空间来进行区分。下面是一个简单的例子展示如何设置两个不生产者: ```java import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("producerOne") public class ProducerServiceOne { @Autowired private RocketMQTemplate rocketMQTemplate; public void sendMessage(String topic, String message){ this.rocketMQTemplate.convertAndSend(topic,message); } } @Service("producerTwo") public class ProducerServiceTwo { @Autowired private RocketMQTemplate rocketMQTemplate; public void sendMessage(String topic, String message){ this.rocketMQTemplate.convertAndSend(topic,message); } } ``` 上述代码展示了通过注入 `RocketMQTemplate` 来发送消息的方法,并且每个服务都注册为独立的服务组件以便于管理。 #### 消费者配置与实现 对于消费者配置,则可以利用 `@RocketMQMessageListener` 注解指定监听的主题以及消费组名。这里给出一个多消费者示例: ```java import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; import org.apache.rocketmq.spring.core.RocketMQListener; import org.springframework.stereotype.Service; @Service @RocketMQMessageListener(consumerGroup = "consumer_group_one", topic = "test_topic") public class ConsumerOne implements RocketMQListener<String> { @Override public void onMessage(String message) { System.out.println("Received by consumer one:" + message); } } @Service @RocketMQMessageListener(consumerGroup = "consumer_group_two", topic = "test_topic") public class ConsumerTwo implements RocketMQListener<String> { @Override public void onMessage(String message) { System.out.println("Received by consumer two:" + message); } } ``` 这段代码说明了怎样使用自定义的消费者去订阅相主题下的消息流并分别处理接收到的消息[^2]。 #### 应用程序属性文件中的配置 最后,在应用的配置文件 (`application.properties`) 中还需要指明连接至哪个 NameServer 地址以及其他可能需要调整的相关参数: ```properties spring.rocketmq.name-server=localhost:9876 spring.rocketmq.producer.group=my_producer_group ``` 这一步骤是为了让客户端知道去哪里寻找集群节点的信息从而建立通信链路。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值