RabbitMQ 系列之:消息的高可用投递方案

在消息的投递过程中,不可能保证消息总是 100% 的能够完全投递成功的。因此对于一些核心的业务系统,在实现之前就要考虑消息的高可用投递。以下给出两种实现方案,可供参考。

消息落库打状态

在消息发送之前先进行落库(mq-msg)打状态(status=0)在开始发送消息,如果发送消息之后回掉过来的结果是成功的情况,将消息打状态为(status=1),如果消息发送之后因为网络通信的原因未能正常的收到响应,就不会改动消息当前状态。

后台建立一个分布式定时任务,定时对(mq-msg)库里失败的消息进行抓取,记得设置一个超时的值,例如消息落库 3 分钟还未被改动的,避免了消息一旦落库就被定时任务抓取,抓取到 status=0 的消息后做重试操作,可以设置重试次数,假设真的因为一些异常原因可以将消息再次打状态为(status=2)做报警,人工核查。

实现流程图

一些问题

这种方案在发送消息前需要先确保消息落库,很明显增加了一次数据库的写入操作,在高并发场景下就多了道 I/O 操作,如果还处业务的核心链路,应尽量减少这种 I/O 操作,那么再看下第二种方案。

延迟投递与二次确认检查

同时发送两条消息,第二条消息为延迟投递(5s 后投递),第一条消息如果投递成功在去 mq-msg 库写一条消息,待第二条延迟消息过来之后先去检查该消息在 mq-msg 库是否存在,如果存在且是成功的,就丢弃直接 confirm,如果检查失败,再重新推动发送消息。

实现流程图

这种方式的优点在于解耦了两次消息的 DB 写入。