1、微服务架构数据一致性问题

 电商为例,支付,订单,积分功能抽成三个服务,每个服务都有独立的数据库做数据存储。无论是修改订单状态失败,还是增加积分失败,都会导致数据的不一致

支付-------->订单--------->积分

为了解决这种问题,最好的方法避免微服务,实现本地事务保证数据的强一致性。但微服务架构中,每个服务都有自己的数据库,导致微服务系统不能简单的满足本地事务的特性。

 分布式系统CAP理论和BASE理论

C:一致性,所有数据变动都是同步的

A:可用行,即在可以接受的时间范围内正确的响应客户的请求

P:分区容错性,即某节点或网络出现故障时,系统仍能提供满足一致性和可用性的服务

BASE理论

BA:基本可用

S:软状态,状态可以有一段时间不同步

E:最终一致,最终数据是一致的就可以了

BASE理论主要是通过牺牲强一致性来保证系统的可用性。

解决方案:

1、二阶段提交协议

准备阶段,事务管理器向数据管理器都发送准备操作,数据管理器操作之后,成功,返回OK,如果有一个是失败,事务管理器便回滚该状态,否则就是提交事务,流程结束

java微服务sql一致性 微服务之间数据一致性_数据库

优点:

能够解决失去一致性的问题,严格遵行ACID的特性

缺点:

  • TM 通过 XA 接口与各个 RM 之间进行数据交互,从第一阶段的准备阶段,业务所涉及的数据就被锁定,并且锁定跨越整个提交流程。在高并发和涉及业务模块较多的情况下对数据库的性能影响较大。
  • 二阶段是 反可伸缩模式 的,业务规模越大,涉及模块越多,局限性越大,系统可伸缩性越差。
  • 在技术栈比较杂的分布式应用中,存储组件有很多 不支持 XA 协议

2、可靠消息最终一致性

利用MQ组件实现的二阶段提交

java微服务sql一致性 微服务之间数据一致性_微服务_02

基本操作

上游应用发送待确认消息到可靠消息系统

可靠消息系统保存待确认消息并返回

上游应用执行本地业务

上游应用通知可靠消息系统确认业务已执行并发送消息。

可靠消息系统修改消息状态为发送状态并将消息投递到 MQ 中间件

java微服务sql一致性 微服务之间数据一致性_数据库_03

  1. 下游应用监听 MQ 消息组件并获取消息
  2. 下游应用根据 MQ 消息体信息处理本地业务
  3. 下游应用向 MQ 组件自动发送 ACK 确认消息被消费
  4. 下游应用通知可靠消息系统消息被成功消费,可靠消息将该消息状态更改为已完成

3、TCC

java微服务sql一致性 微服务之间数据一致性_java微服务sql一致性_04

第一阶段:主业务服务分别调用所有从业务服务的 try 操作,并在活动管理器中记录所有从业务服务。当所有从业务服务 try 成功或者某个从业务服务 try 失败时,进入第二阶段。

第二阶段:活动管理器根据第一阶段从业务服务的 try 结果来执行 confirm 或 cancel 操作。如果第一阶段所有从业务服务都 try 成功,则协作者调用所有从业务服务的 confirm 操作,否则,调用所有从业务服务的 cancel 操作。

在第二阶段中,confirm 和 cancel 同样存在失败情况,所以需要对这两种情况做 异常处理 以保证数据一致性。

  1. Confirm 失败:则回滚所有 confirm 操作并执行 cancel 操作。
  2. Cancel 失败:从业务服务需要提供自动 cancel 机制,以保证 cancel 成功。

目前有很多基于 RPC 的 TCC 框架,但是不适用于微服务架构下基于 HTTP 协议的交互模式

5、最大努力通知型

上游应用,发消息到MQ队列

下游应用,接受请求,并返回通知结果

最大努力通知服务,监听消息队列,将消息存储到数据库中,并按照规则调用下游应用的发送通知接口

java微服务sql一致性 微服务之间数据一致性_java微服务sql一致性_05