URL
date
AI summary
slug
status
tags
summary
type
RocketMQ使用docker启动导致2台消费者实例instanceId相同
如果不进行人为设置的话,1个rocketmq-client和broker只会建立一条连接,producer和consumer和broker交互都通过这一条连接。维护这条连接的是一个单例对象MQClientInstance。
如果是开启了message trace,那么会额外建立一条连接。
默认情况下,clientId的生成逻辑是在基类方法里:
org.apache.rocketmq.client.ClientConfig#buildMQClientId
clientId由clientIp、instanceName、unitName组成。而instanceName、unitName一般在使用时也不会特意去修改(默认值分别为"DEFAULT"和null),所以clientIp便成了唯一的区分。而我们的应用又是通过docker启动的,并且network使用的是bridge模式,所以每个容器的ip其实都是自己的私有ip。这就导致了2个容器用到了同一个ip,如172.17.0.14
而默认的rebalance分配队列的策略是AVG,源代码如下所示。
而如果发生了上述的2个Consumer的clientId相同,那么此时cidAll就是2个同名的cid组成的list
如果你通过看代码没办法快速得到答案,我们也可以写个测试用例来验证一下
假设这个topic总共有4个队列,2个同clientId的消费实例。那么对于这2个消费实例来说,都会分配到queue0和queue1,而queue2和queue3却无人分配。因此造成的后果就是queue0和queue1的消息会重复消费,而queue2和queue3的消息一直堆积在队列中。
下面这张图展示了RocketMQ-Console里观察到的队列消费信息
下面这张图展示了2台消费实例消费到了重复的消息
参考
- 作者:黑微狗
- 链接:https://blog.hwgzhu.com/article/rocketmq-client-running-with-docker
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章