MQ分布式环境下保持数据一致性

业务场景:

支付宝的余额系统与蚂蚁金服的余额宝是两个对立的平台,相互之间通过ActiveMQ进行通信。当用户把1000块钱从余额存进余额宝的时候,余额系统数据库减1000,然后发送一个消息到MQ,余额宝端接收到这个消息后,在其数据库中加1000.

MQ分布式环境下保持数据一致性_第1张图片

可能存在的问题:

1. 消息丢失问题。用户发起1000块钱的转账,支付宝余额平台减了1000,触发消息放到了队列,余额宝端成功消费了消息,但是在修改数据库的时候发生了异常,进行了回滚。这时候消息就丢失了。

解决办法,支付宝余额端要有消息重发机制。当余额宝端接受到消息之后,更新完数据库之后,要回调支付宝平台的接口,告诉支付宝我这里操作成功完成了。如果长时间没有回调,则支付宝端应该察觉到问题才可以。我们可以在支付宝余额端建立一个账本,记录每一次的操作。这个账本就是历史订单表。创建一个订单历史表,message_id用来定义每一次操作,并且会将这个值放到消息队列中。status字段用于标记余额宝端是否成功回调了告诉了支付宝这次操作是否成功。字段值为confirmed或者unconfirmed.

MQ分布式环境下保持数据一致性_第2张图片

余额宝端有一个job在一直监视着订单历史表,如果发现有记录一直处于unconfirm状态,会再次发一个相同的消息给余额宝端。这样就避免了消息丢失问题。

MQ分布式环境下保持数据一致性_第3张图片

 

2. 这样会引发新的问题,重复消费问题。余额宝端成功消费了消息,成功更新了数据库,都是由于网络原因回调失败,那么支付宝端会再次发出一个MQ,这样如果余额宝端再次消费,那么就成了增加2次1000块。解决办法,可以在余额宝端也加一个账本,记录历史记录。这个表中包含message_id,每次成功更新数据库之后,就在这个表中加入一条记录。那么第二次同一个消息过来的时候,因为是用一个message_id,那么就会被丢弃。这样,消息重复问题也就解决了。

 

你可能感兴趣的:(技术积累)