应用连接两个RocketMQ集群,只连接其中一个集群问题分析

项目场景:

应用中需要连接两个RocketMQ集群,即就是两个不同的NameServer,消费两个集群里的消息。(RocketMQ Client 版本4.4.0)


问题描述:

应用启动后在RocketMQ控制台发现,两个消费都注册到同一个集群(期望是根据配置分别注册到不同的NameServer)

 

        DefaultMQPushConsumer consumer1 = new DefaultMQPushConsumer();
        consumer1.setConsumerGroup(groupName);
        consumer1.setNamesrvAddr(namesServer1);
        consumer1.start();

        DefaultMQPushConsumer consumer2 = new DefaultMQPushConsumer();
        consumer2.setConsumerGroup(groupName);
        consumer2.setNamesrvAddr(namesServer2);
        consumer2.start();

 


原因分析:

初步估计是配置的两个NameServer只有一个生效,把两个配置改为一致后,消费者注册正常,后面查看了RocketMQ源码,发现了问题所在。

org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl#start();

//获取MQ客户端实例
this.mQClientFactory = MQClientManager.getInstance().getAndCreateMQClientInstance(this.defaultMQPushConsumer, this.rpcHook);

 

    /**
    * 构建MQ客户端id,规则是IP@instanceName@unitName
    * instanceName默认为进程id
    */
    public String buildMQClientId() {
        StringBuilder sb = new StringBuilder();
        sb.append(this.getClientIP());

        sb.append("@");
        sb.append(this.getInstanceName());
        if (!UtilAll.isBlank(this.unitName)) {
            sb.append("@");
            sb.append(this.unitName);
        }

        return sb.toString();
    }

    
    if (this.instanceName.equals("DEFAULT")) {
       this.instanceName = String.valueOf(UtilAll.getPid());
    }

 

    public MQClientInstance getAndCreateMQClientInstance(final ClientConfig clientConfig, RPCHook rpcHook) {
        String clientId = clientConfig.buildMQClientId();
        MQClientInstance instance = this.factoryTable.get(clientId);
        if (null == instance) {
            instance =
                new MQClientInstance(clientConfig.cloneClientConfig(),
                    this.factoryIndexGenerator.getAndIncrement(), clientId, rpcHook);
            MQClientInstance prev = this.factoryTable.putIfAbsent(clientId, instance);
            if (prev != null) {
                instance = prev;
                log.warn("Returned Previous MQClientInstance for clientId:[{}]", clientId);
            } else {
                log.info("Created new MQClientInstance for clientId:[{}]", clientId);
            }
        }

        return instance;
    }

 由上图可以看出MQClientInstance是通过clientId在factoryTable内存中查询的,默认一个进程中的clientId是一致的,因此很好的解释了,我们出现的问题。


解决方案:

由上可以知道解决问题的方案就是多个MQClient需要使用不同的ClientId,通过为消费者设置不同的instanceName或者unitName可以解决。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RocketMQ一个分布式的消息队列系统,支持高可用的集群部署方式。以下是RocketMQ集群部署的步骤: 1. 下载RocketMQ,解压缩后进入bin目录。 2. 修改conf文件夹下的配置文件,包括broker.conf、namesrv.conf、logback_broker.xml和logback_namesrv.xml等。其中,broker.conf和namesrv.conf是RocketMQ的核心配置文件,需要根据实际情况进行修改。 3. 启动NameServer。在bin目录下执行命令:nohup sh mqnamesrv &。这个命令将会在后台启动NameServer。 4. 启动Broker。在bin目录下执行命令:nohup sh mqbroker -n localhost:9876 &。这个命令将会在后台启动一个Broker实例,它会自动注册到NameServer上。 5. 配置集群。在配置文件broker.conf中,需要配置brokerClusterName和brokerName,这两个参数用于标识一个Broker所属的集群和Broker的名字。在同一个集群中,每个Broker的brokerClusterName必须相同,brokerName必须不同。 6. 启动多个Broker实例。在不同的服务器上启动多个Broker实例,它们都需要连接到同一个NameServer上。在启动Broker实例时,需要使用不同的brokerName参数。 7. 配置负载均衡。在配置文件broker.conf中,可以配置brokerIP1~4参数,这些参数用于配置Broker的IP地址。在同一个集群中,多个Broker实例之间可以通过负载均衡的方式进行消息的转发。 以上是RocketMQ集群部署的基本步骤,具体操作可以根据实际情况进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值