rocketmq 启动多个生产者实例

最近在公司的项目中遇到一个坑,在一个应用里面启动多个实例的时候消息总是只能发送到其中一个实例对应的mq服务器上去,通过反射跟踪发现这2个实例的brokerAddrTable地址是一样的,开始还以为是配置设置的NamesrvAddr不对,后面打印出来发现NamesrvAddr是正常的,但是brokerAddrTable就是不对,始终指向第一个启动的brokerAddrTable地址。后面跟踪源代码发现在再启动生产者的时候会创建一个mqclient的工厂(如下),

跟进工厂方法,发现它是从一个map里面获取对应的实例,map的key就是clientid,

从下面的源代码中我们可以看到clientid是通过clientip和实例名称还有unitname组成的,instacename是从系统属性中获取的,默认是default。如果是默认值,启动的时候mq会将instancename设置为当前的进程id。也就是说我们创建client的时候如果不设置instancename,那么同一个应用中所用的client都是同一个。即使设置了NamesrvAddr,也只是改变了NamesrvAddr这个属性,它对应的实例发送通道还有其他的心跳还是同一个。如果我们想创建多个实例,那么必须设置不同instancename

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RocketMQ是一种基于Java的分布式消息中间件,它具有高可靠、高吞吐量、易于扩展等特点,已经被广泛应用于各种场景,如电商、社交、金融等。下面是RocketMQ在项目中的一个简单使用实例: 1. 引入依赖 在项目的pom.xml文件中添加RocketMQ的依赖: ``` <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.8.0</version> </dependency> ``` 2. 配置RocketMQ 在项目中添加一个配置类,用于配置RocketMQ的相关参数,如下所示: ``` @Configuration public class RocketMQConfig { @Value("${rocketmq.namesrvAddr}") private String namesrvAddr; @Bean public DefaultMQProducer defaultMQProducer() throws MQClientException { DefaultMQProducer producer = new DefaultMQProducer("producer_group"); producer.setNamesrvAddr(namesrvAddr); producer.start(); return producer; } @Bean public DefaultMQPushConsumer defaultMQPushConsumer() throws MQClientException { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer_group"); consumer.setNamesrvAddr(namesrvAddr); consumer.subscribe("topic", "*"); consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { // 处理消息 return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); consumer.start(); return consumer; } } ``` 其中,namesrvAddr是RocketMQ的nameserver地址,producer_group和consumer_group是生产者和消费者的组名,topic是消息的主题。在上面的配置中,我们创建了一个生产者和一个消费者,并且为消费者注册了一个消息监听器,用于处理接收到的消息。 3. 发送消息 在需要发送消息的地方,注入DefaultMQProducer对象,然后调用send方法即可,如下所示: ``` @Autowired private DefaultMQProducer defaultMQProducer; public void sendMessage(String message) throws Exception { Message msg = new Message("topic", "tag", message.getBytes(RemotingHelper.DEFAULT_CHARSET)); SendResult result = defaultMQProducer.send(msg); System.out.println(result); } ``` 其中,"topic"是消息主题,"tag"是消息标签,message是消息内容。 4. 接收消息 在消费者注册的消息监听器中,处理接收到的消息即可,如下所示: ``` @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { for (MessageExt msg : msgs) { System.out.println("Receive message: " + new String(msg.getBody())); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } ``` 在上面的代码中,我们通过循环遍历msgs列表,处理接收到的消息。最后,返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS表示消息已经被成功消费。 以上是RocketMQ在项目中的简单使用实例,当然,RocketMQ还有很多其他的功能和用法,可以根据具体需求进行深入学习和使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值