我整理了一下,把老师说的话,敲了一下记录下来发了个博客
概述
首先对于广播模式的消息, 是不存在消息重试的机制的,即消息消费失败后,不会再重新进行发送,而只是继续消费新的消息。
而对于普通的消息,只要消费者消费消息失败后,就会自动进行重试.
如何让消息进行重试
集群消费方式下,消息消费失败后期望消息重试,需要在消息监听器接口的实现中明确进行配置。可以有三种配置方式:
- 返回Action.ReconsumeLater-推荐
- 返回null
- 抛出异常
如何让消息失败不进行重试
如果希望消费失败后不重试,可以直接返回Action.CommitMessage。
重试消息如何处理
如果你消息消费失败,就会自动进入重试队列里面. 重试队列是RocketMQ自动生成的,它会给你每个消费者组创建一个重试队列, 你消息一旦消费不成功,就会进入到这个队列里面进行不断的重试.
重试的消息会进入一个 “%RETRY%”+ConsumeGroup 的队列中。
消息重试次数以及间隔时间
然后RocketMQ默认允许每条消息最多重试16次,每次重试的间隔时间如下:
重试次数 | 与上次重试的间隔时间 | 重试次数 | 与上次重试的间隔时间 |
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级别。
messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
这个重试时间可以将源码中的org.apache.rocketmq.example.quickstart.Consumer里的消息监听器返回状态改为RECONSUME_LATER测试一下。
自定义重试间隔时间
关于这个重试次数,RocketMQ可以进行定制。例如通过consumer.setMaxReconsumeTimes(20);将重试次数设定为20次。当定制的重试次数超过16次后,消息的重试时间间隔均为2小时。
需要注意配置覆盖问题:
消息最大重试次数的设置对相同GroupID下的所有Consumer实例有效。并且最后启动的Consumer会覆盖之前启动的Consumer的配置。
消息重试超过上限怎么办?
如果重试次数设置的是16,当消息重试16次后仍然失败,消息肯定是不能丢掉的,消息将不再投递。转为进入死信队列。
RocketMQ的死信队列要比RabbitMQ的死信队列简单的很多.不需要那么繁琐的配置.当你消息要放入死信队列的时候,RocketMQ默认就会给你创建死信队列.
死信队列的创建规则和重试队列的创建规则是差不多的, 死信队列topic创建规则是是把消费者组的前缀加了个 %DLQ%了.
关于MessageId的问题需要注意
在老版本的RocketMQ中,一条消息无论重试多少次,这些重试消息的MessageId始终都是一样的。
但是在4.7.1版本中,每次重试MessageId都会重建。