apache / apache/rocketmq-client-cpp

Duplicate consumption question?

未關閉
#362 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
enhancement
主要語言
C++
星號
393
分支
167
PR 合併指標
30 天內沒有已合併 PR

描述

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. 线程1: 队列queue1的请求A触发Add mq,绑定cb1,生成 cb1 = getAsyncPullCallBack(A,queue1)
2. 线程2: 队列queue1的请求A触发Drop mq,然而只是设置了下drop flag,实际清理工作在pull循环里面
3. 线程3: 队列queue1的请求B触发Add mq,绑定cb1 = getAsyncPullCallBack(B,queue1),因为cb是复用的,返回了和线程1一样的cb1, 这是cb1绑定是B,所以线程1这时也绑定了B
4. 线程1: 将cb1加到pull循环工作,原本希望将A加入pull循环结果却将B加入到循环
5. 线程3: 将cb1加到pull循环工作,将B加入到循环
6. 这时就2个pull循环在在跑请求B,导致重复消费
因为cb是复用的而绑定的requst随时有可能被别的request替换掉导致加入pull循环时候导致重复消费;

貢獻指南

開啟貢獻指南

研究方向

從 src/consumer/DefaultMQPushConsumerImpl.cpp 第 799 行附近開始,追蹤 m_PullCallback、getAsyncPullCallBack 以及經過並行 Add 和 Drop 操作的 pull 迴圈。重現所描述的 queue1 序列,並驗證一個請求不會導致兩次進入 pull 迴圈或重複消費。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
cpp
領域
distributed-systems
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。