rocketmq超时重试导致的重复消费问题处理 有更新!

  |   0 评论   |   1,423 浏览

公司各系统交互使用的是RockeMQ 3.x版本的消息中间件。RocketMQ是以consumer group + queue 为单位来管理消费进度的,以一个consumer offset 标记这个组在queue上的消费进度,依靠这个进度来判定从哪里开始消费,每次消费成功后,本地的消费进度会被更新,然后定时器(这个时间很短)去同步到broker,来持久化消费进度,但是每次记录消费进度,只会把一批消息中最小的offset值记为消费进度值,

这种机制会带来一个潜在的重复问题——由于消费进度只是记录了一个下标,就可能出现拉取了100条消息如 2101-2200的消息,后面99条都消费结束了,只有2101消费一直没有结束的情况,这种情况下,RocketMQ为了保证消息肯定被成功消费,消费进度只能维持在2101,直到2101也被消费结束了,本地的消费进度才能标记2200消费结束。

在这种设计下,就有消费大量重复的风险。如2101在还没有消费完成的时候消费实例突然退出(机器断电,或者被kill)。这条queue的消费进度还是维持在2101,当queue重新分配给新的实例的时候,新的实例从broker上拿到的消费进度还是维持在2101,这时候就会又从2101开始消费,2102-2200这批消息实际上已经被消费过还是会投递一次。

故障的原因就是因为程序中出现了一条7月21日的消息一直没有返回成功,导致offset一直卡在那里,系统进行正常更新流程时候重启了服务,再次启动就会从7月21的那条消息开始重复消费。

对于这个消息被重复消费BUG,目前初步商讨做以下更改

1.消费端实现消费幂等,重复的消息忽略,不再消费,并记录日志。

2.消费端增加消息消费超时机制(避免卡offset的问题)

3.生产端针对同一个任务避免推送多次消息,这并不能完全避免,仅允许手动重试。



---------------------------
本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动。
转载请注明:文章转载自 xiajl.cn

评论

发表评论