消息可靠性保障
消息补偿机制
步骤:
如果正常情况,生产者投递消息到队列,消费者监听队列消费,那就万事大吉,但是有很多不可控原因,网络波动,程序异常,等等,导致不是每次都正常投递消费,所以我们要做到消息可靠投递消费,采用消息补偿机制
- 生产者将数据写入到本地数据库
- 生产者投递消息到消息队列 Q1
- 过段时候生产者再次发送消息到队列 Q2,与第②步投递的消息相同
- 消费者监听队列 Q1,消费
- 消费者将消息写入到消费者的本地数据库
- 消费者将消息投递到另外一个队列 Q3
- 一个独立的回调检查服务会监听队列 Q3,监听 Q3 [消费者投递的消息] 里的消息,如果消费者正常消费,那么Q3肯定会有该消息
- 将监听的 Q3 的消息写入到回调检查的本地数据库
- 回调检查服务监听 Q2 [生产者延迟投递的消息]
- 将监听的 Q2 的消息写入到本地数据库,由于第⑧步已经写入过一次,所以肯定会主键冲突(一般消息都携带唯一主键),说明成功
- 如果 Q2 写入成功,说明第 8 步监听Q3 没有该消息,说明消息消费失败,通知生产者再次投递该消息
仍然有其他的问题:
- 假设第 2 步,第 3 步都投递失败,Q1 ,Q2 里都没有该消息,消费者不会消费,回调检查服务监听 Q2 也没有消息
- 采用独立的定时检查服务,查看生产者的数据库与回调检查的数据库数据是否一致。如果回调检查的数据库数据少于生产者数据库,定时检查服务通知生产者投递
- 假设第④⑤⑥步网络波动,导致消费者消费完,过了很久10分钟才投递到 Q3,而第③步只延迟了5分钟,回调检查服务监听 Q2 Q3,当第5分钟的时候,发现 Q2 里有消息,就进行第⑩步,数据检查,发现回调服务的数据库里写入成功,以为消费者消费失败,通知了生产者重发,而生产者又发送了一条一样的消息。消费者有可能重复消费。
产者重发,而生产者又发送了一条一样的消息。消费者有可能重复消费。- 幂等性保障