闲着研究了下RocketMQ消费失败消息的处理逻辑这里记录下,更细化说这里只讨论Push模式(其实实现还是Pull的模式)非顺序消费的情况Pull和顺序消息这里暂时不做讨论哈~(还没研究- -)
消费失败处理逻辑
消费成功的情况RockeMQ会通过移动消费offset位点向前来标示消息已被处理
而对于业务处里失败的消息采用的策略是将消息回发回Broker(并存放到一个%RETRY%XX的topic中), 大家一听可以想到的是回发broker这时候broker挂了怎么办?
回发失败的时候会在本机启动个task来重试..恩 然后这时候consumer机器挂了了怎么办重试没了,难道丢消息?
所以为了保证consumer掉电不丢消费失败且回发失败的消息,代码里保证offsetManage(local or remote)中offset不会前移超过重发失败消息的offset,这样可以保证在下次需要,如果下次consumer活过来时(这时一定会从offsetManage中取offset, 恩其实正常运行中不会每次都取, 顺序消息除外...),一定可以重拉到消费失败的消息(后面会提到这个的代价是会重复拉到很多上次已经消费的消息,不过业务同学的代码都是幂等的,所以逃~)
对于消费失败但回发成功的消息,会直接更新offset假装认为那几条消息已经被消费成功,因为他们已经转生在%RETRY%XX topic里作为新消息等待消费了~当前消费者可以专注于干其他事情.(补充: RERTRY topic实际会带上delay所以实际是先SCHEDULE_TOPIC然后再%RETRY%XX, 这个具体见其他同学关于delay消息的解析~)
可以看到,重发这种模式是不会丢消息的,即使broker挂了,consumer挂了,一定会消费到,虽然可能获得很多不想要的重复消息- -
为啥这么搞
写本文