RabbitMQ消息的100%投递

生产端的可靠性投递数据库

  • 保障消息的成功发出
  • 保障MQ节点的成功接收
  • 发送端收到MQ节点确认应答
  • 完善的消息进行补偿机制

解决方案服务器

  • 消息落库,对消息状态进行打标
  • 消息的延迟投递,作二次确认,回调检查

消息落库架构图网络

上图中BIZ DB为咱们的业务库,比方说保存订单;MSG DB为消息库,保存咱们发送到MQ消息。若是在Step 3的时候,网络出现故障,Confirm机制没有收到broker的消息确认。咱们须要设置一个时间临界点,好比说5分钟,检索出消息库中状态为0的消息,经过分布式定时任务,好比XXL-Job或者Elastic-Job。但有可能出现消息刚发出去,尚未Confirm成功,定时任务就已经启动了,并把发送成功的消息确认为未成功,因此咱们须要有一个Step 6,给入库消息一个最大的容忍时间,好比说2分钟到5分钟。好比消息入库的时候须要带上时间,咱们取出状态为0的消息造成一个集合,而后过滤该集合的时间为2分钟以上的消息进行从新发送。因为MQ消息的配置自己有问题的状况下(好比说路由,队列,交换机),会出现消息永远没法发送成功,这个时候咱们须要有一个消息重试的机制,好比3次,若是3次都没有发送成功,则更新该消息状态为2,表示失败。架构

可是这种方式有必定的局限性,由于要作数据库的二次入库操做,磁盘io会成为瓶颈,在高并发的场景下并不合适。因为咱们的业务入库是必须的,因此咱们要考虑消息入库是否能够取消。因此咱们要考虑第二种方式:消息的延迟投递,作二次确认,回调检查。并发

这里的Upstream service为咱们的上流业务,咱们确定要作的是进行业务入库,而后再发消息到Broker,这里的不一样在于Step2,Step2须要再发一条消息,但这条消息是一个延迟消息(这种延迟消息并非死信队列那种延迟消息,咱们能够用DelayQueue来发这条消息),多是2到5分钟以后才发出去的,该消息与Step1虽然消息内容同样,可是它们投递的队列不一样,该队列被Call back service监听。Downstream service为MQ消费者,但它同时也是消息投递者,它会在Step4发送一个confirm消息(该消息也是一个MQ消息)到Broker,可是这条消息并非发给上流生产者的,而是发给Call back service的,Call back service做为消息消费者收到这条消息,而后作一个消息的持久化存储,存入数据库中。3到5分钟以后,Call back service收到延迟发送的Step2的消息,再去对比消息数据库中的消息,更新消息数据库中的状态为1。若是在此过程当中,Downstream service没有发送消息给Call back service,则消息数据库中没有这条消息,当Call back service收到Step2的延迟消息的时候,就经过RPC或者Restful从新调用upstream中的业务库检查后,再从新发送一条step1消息,走下一个流程。分布式

以上的这个方案并不能保证100%的消息投递,可是它对于第一种方案的好处是少进行了一次DB操做,保证高并发的性能。好比说第一种方式的吞吐量为1000,那第二种方式的吞吐量就能够翻倍到2000,能够节省一台服务器。这里把消息补偿机制从第一种方式的嵌入到核心链路给解耦为一个单独的微服务,核心链路则只有消息发送到消息处理。同时下游业务处理应该加上消息的幂等,确保只处理一个消息。微服务

相关文章
相关标签/搜索