基于消息队列的数据同步

业务背景

由于公司业务需要,我们要把线上的交易数据实时同步到第三方应用。数据同步有三个基本要求:

  • 尽可能接近实时的同步
  • 同步的数据必须和我们线上数据库的数据一致
  • 不能影响正常的交易

业务分析

为了满足以上业务场景,我们确实要考虑不少事情,我们来一一分析!!!

首先实时同步,实时同步只能同步接口的形式上送,甚至不能通过脚本的形式上送,那么剩下来只有两种方案了,要么改造原来接口同步上送,要么采用异步的形式上送。

其次数据一致,数据要想保持一致必须有重试机制。

最后不影响正常交易,既然要想不影响正常交易,同步的方式就不可取了,基于第二点的重试机制,这个时候使用消息队列是非常合适不过的。

技术选型

阿里云RocketMQ实现异步调用第三方接口。选用阿里云的Mq,我们就不用关心Mq的具体实现了,只需要关注我们自己的业务就好了。

技术调研

消息队列 MQ 是基于发布/订阅模型的消息系统。消费者,即消息的订阅方订阅关注的 Topic,以获取并消费消息。由于消费者应用一般是分布式系统,以集群方式部署,因此消息队列 MQ 约定以下概念:

  • 集群:使用相同 Group ID 的消费者属于同一个集群。同一个集群下的消费者消费逻辑必须完全一致(包括 Tag
    的使用)。详见订阅关系一致。
  • 集群消费:当使用集群消费模式时,消息队列 MQ 认为任意一条消息只需要被集群内的任意一个消费者处理即可。
  • 广播消费:当使用广播消费模式时,消息队列 MQ 会将每条消息推送给集群内所有注册过的消费者,保证消息至少被每个消费者消费一次。

根据我们的业务场景我们选择了集群消费模式,因为我们这里是入账操作,所以只需调用一次即可,同时对于调用失败的场景采用消息队列的重试机制。

业务场景图基于消息队列的数据同步_第1张图片

技术方案设计

同步给第三方的订单只需支付成功和退款成功的,所以根据原有逻辑筛选出此类订单,并放入消息队列。第三方系统做幂等性校验,即一个流水号只能同步成功一次。

我们的系统是分布式服务,目前单日130万笔的交易6台服务器,消息队列的消费端也是部署在这6台服务器上,方便后续扩展。

风险监控

对此消息的Topic进行了监控,阀值3000开始短信报警。

踩过的坑

现象

消息堆积报警,一度堆积到近10万条消息

原因

第三方接口返回的业务码不明确,我们做异常处理,消息没有提交,所以大量消息堆积。

影响

  1. 消息队列有挂的风险,影响正常线上交易。
  2. 线上服务器资源紧张。

解决方案

解决方案之前在公众号里写过了,这里放个链接吧解决方案

总结

本文是一个业务解决方案,从业务场景到技术选型,最后到业务设计和踩过的一些坑。

后记

后续系统运行过程中发现有订单同步丢失的问题,根据日志排查发现,是我们服务调用阿里的rocketMq发送消息失败,属于网络波动,与阿里云Mq连接失败,对于这种情况,我们系统也做了优化,对于发送失败的消息,采取了重试机制。

扫码关注个人公众号,精彩不错过

基于消息队列的数据同步_第2张图片

你可能感兴趣的:(java,mq,数据同步,大数据,架构)