rocketmq-client-cpp
rocketmq-client-cpp copied to clipboard
Duplicate consumption question?
https://github.com/apache/rocketmq-client-cpp/blob/d0f65a191b9e9609939da719d13548898d73f225/src/consumer/DefaultMQPushConsumerImpl.cpp#L799
并不是说这行有bug,而这里m_PullCallback是复用的,而绑定request是可变的。在多client进程并发重启时候,容易触发某个queue短时间内被Add、Drop然后又Add,就会触发重复消费case:
- 线程1: 队列queue1的请求A触发Add mq,绑定cb1,生成 cb1 = getAsyncPullCallBack(A,queue1)
- 线程2: 队列queue1的请求A触发Drop mq,然而只是设置了下drop flag,实际清理工作在pull循环里面
- 线程3: 队列queue1的请求B触发Add mq,绑定cb1 = getAsyncPullCallBack(B,queue1),因为cb是复用的,返回了和线程1一样的cb1, 这是cb1绑定是B,所以线程1这时也绑定了B
- 线程1: 将cb1加到pull循环工作,原本希望将A加入pull循环结果却将B加入到循环
- 线程3: 将cb1加到pull循环工作,将B加入到循环
- 这时就2个pull循环在在跑请求B,导致重复消费 因为cb是复用的而绑定的requst随时有可能被别的request替换掉导致加入pull循环时候导致重复消费;
当前复用PullCallback的设计比较差