之前在学习rocketmq源码的时候,阅读了丁老师的《rocketmq技术内幕》
在写到broker异常关闭再恢复的情况下会造成大量的消息重复消费问题。我认为这里是有误的。
首先我们知道无论broker是否正常异常恢复,都是先恢复逻辑队列CousumeQueue的。然后再根据本地store目录下是否有abort文件来判断关闭的时候是正常还是异常。
abort:当我们正常启动一个broker时(包括恢复和创建),如果是恢复的情况下会在恢复完成后在store目录下创建一个abort文件。如果不是恢复,则会跳过恢复的过程然后在store文件下创建一个abort文件。这个abort文件的作用是当broker正常关闭的情况下,代码中事先注册了一个jvm的钩子函数,会调用销毁这个abort文件的方法。如果你在broker没启动的情况下,去broker服务器上去检查本地文件,在store目录下是否有abort文件。如果有则证明是异常关闭,反之是正常关闭。
当恢复完CousmerQueue逻辑队列后,开始恢复broker。broker恢复的逻辑是根据是否有abort文件的存在与否来进行判断走异常恢复的流程还是走正常恢复的流程。这里就不BB正常恢复的流程了。
异常恢复流程:
读取commitlog文件,从倒数第一个开始从后向前遍历,判断commitlog队列中第一条消息的magic_code是否符合条件,落盘时间是否大于0,落盘时间是否小于checkpoint文件中的最新落盘时间。这个checkpoint最新落盘时间一般都是在reputMessage的时候触发更新的,即往Consumequeue逻辑消息队列中写数据的时候。还有就是正常关闭的时候 会在最后更新一下这个时间。
当三个条件都满足的情况下将这个commitlog取出。(这个commitlog如果这三个条件满足说明它前面的commitlog

最低0.47元/天 解锁文章
1354





