延迟消息与消费重试的关系
RocketMQ提供了消息重试的能力,在并发模式消费消费失败的情况下,可以返回一个枚举值RECONSUME_LATER,那么消息之后将会进行重试。如:
org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently#consumeMessage
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
long currentTimes = this.consumeTimes.incrementAndGet();
System.out.printf("%-8d %s%n", currentTimes, msgs);
if (Boolean.parseBoolean(returnFailedHalf)) {
if ((currentTimes % 2) == 0) {
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
重试默认会进行重试16次。使用过RocketMQ消息重试功能的用户,可能看到过以下这张图:
第几次重试 | 与上次重试的间隔时间 | 第几次重试 | 与上次重试的间隔时间 |
---|---|---|---|
1 | 10 秒 | 9 | 7 分钟 |
2 | 30 秒 | 10 | 8 分钟 |
3 | 1 分钟 | 11 | 9 分钟 |
4 | 2 分钟 | 12 | 10 分钟 |
5 | 3 分钟 | 13 | 20 分钟 |
6 | 4 分钟 | 14 | 30 分钟 |
7 | 5 分钟 | 15 | 1 小时 |
8 | 6 分钟 | 16 | 2 小时 |
细心地的读者发现了,消息重试的16个级别,实际上是把延迟消息18个级别的前两个level去掉了。事实上,RocketMQ的消息重试也是基于延迟消息来完成的。在消息消费失败的情况下,将其重新当做延迟消息投递回Broker。
在投递回去时,会跳过前两个level,因此只重试16次。
到这里,我们的延时消费就搞完了。