RocketMq实战篇:Docker部署Consumer客户端造成的RocketMQ的一场血案(重复消费和NOT_CONSUME_YET)

案情描述

生产者发送消息后,消费者对消息要么不能消费(NOT_CONSUME_YET),要么出现重复消费。在集群模式(CLUSTERING)消息模式下,同一个消息应当向一个消费组下的其中一个消费者发送消息,而不是向消费组下的所有消费者发送消息。而血案就造成了这种重复消费。

在2021-03-16 的代码提交时已经解决了该问题。

在这里插入图片描述 这里的修改,解决了什么 ?

答 : 默认实例名后面加入了时间戳(纳秒的时间戳哦)防止实例名称重复。

防止实例名重名有什么作用 ?

答 : 客户端ID由客户端IP + 实例名(instanceName) + unitName 。源代码如下 :

    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();
    }

客户端Id重复会造成什么问题 ?

答 : 会造成消息NOT_CONSUME_YET 。当然这种情况仅仅会出现在一个消费组有多个消费者,并且使用Docker进行部署消费者的情况。

为什么docker部署会造成客户端Id重复 ?

答:使用docker部署程序,由于docker内是一个相对隔离的环境,并且docker容器内大多数仅仅启动一个进程,而docker启动第一个进程的进程ID都是 1,因此PID是相同的,由于docker内部网络环境也是相对独立的,造成获取的客户端IP也是相同的。这时如果没有设置unitName,就会造成多个消费者客户端客户端ID相同。

为什么消费者客户端ID相同会造成NOT_CONSUME_YET

答 : 名称服务是KV方式存储信息。消费者会注册给命名服务器。如果ID重复,那么名称服务器就无法根据客户端ID找到正确的消费者客户端(也可能能找对,找对了就能消费)。

解决方案:

  • 配置unitName。
  • 客户化InstanceName
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

keep-go-on

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值