总体来说比较迂回,比较巧妙地利用了原顺序存储机制和delay队列机制.
重试消息的consumer发回:
ConsumeMessageConcurrentlyService.java 里 processConsumeResult(ConsumeConcurrentlyStatus, ConsumeConcurrentlyContext, ConsumeRequest){
当失败时设置idx=-1. 发回broker, 如果发送失败. 几分钟后重试.
重试消息的存储:
1.原topic消费
2.消费失败,发回到broker
3.broker 替换为retry,
4. 进一步改成delay_topic 和对应的queue中 ,放入到commitlog后分发. (新的实体,这样commitLog就可往前走了,不用担心数据超过4G删除)
重试消息的消费:
5. 有broker本地delay消息的模拟消费者消费,并将其放入到retryTopic和队列中.
6. 消费者订阅了按组划分的retryTopic, 获取消息并消费.
代码写的不好的一个点:
delayLevel客户端设置为0, 服务端会增加3,并放到message的properties中. 最终转移给新的message.
用了getDelay,但是没有用setDelay, 通过properties整体将delay属性转移了.