1、微服务架构数据一致性问题
电商为例,支付,订单,积分功能抽成三个服务,每个服务都有独立的数据库做数据存储。无论是修改订单状态失败,还是增加积分失败,都会导致数据的不一致
支付-------->订单--------->积分
为了解决这种问题,最好的方法避免微服务,实现本地事务保证数据的强一致性。但微服务架构中,每个服务都有自己的数据库,导致微服务系统不能简单的满足本地事务的特性。
分布式系统CAP理论和BASE理论
C:一致性,所有数据变动都是同步的
A:可用行,即在可以接受的时间范围内正确的响应客户的请求
P:分区容错性,即某节点或网络出现故障时,系统仍能提供满足一致性和可用性的服务
BASE理论
BA:基本可用
S:软状态,状态可以有一段时间不同步
E:最终一致,最终数据是一致的就可以了
BASE理论主要是通过牺牲强一致性来保证系统的可用性。
解决方案:
1、二阶段提交协议
准备阶段,事务管理器向数据管理器都发送准备操作,数据管理器操作之后,成功,返回OK,如果有一个是失败,事务管理器便回滚该状态,否则就是提交事务,流程结束
优点:
能够解决失去一致性的问题,严格遵行ACID的特性
缺点:
-
TM 通过 XA 接口与各个 RM 之间进行数据交互,从第一阶段的准备阶段,业务所涉及的数据就被锁定,并且锁定跨越整个提交流程。在高并发和涉及业务模块较多的情况下对数据库的性能影响较大。
-
二阶段是 反可伸缩模式 的,业务规模越大,涉及模块越多,局限性越大,系统可伸缩性越差。
-
在技术栈比较杂的分布式应用中,存储组件有很多 不支持 XA 协议
2、可靠消息最终一致性
利用MQ组件实现的二阶段提交
基本操作
上游应用发送待确认消息到可靠消息系统
可靠消息系统保存待确认消息并返回
上游应用执行本地业务
上游应用通知可靠消息系统确认业务已执行并发送消息。
可靠消息系统修改消息状态为发送状态并将消息投递到 MQ 中间件
-
下游应用监听 MQ 消息组件并获取消息
-
下游应用根据 MQ 消息体信息处理本地业务
-
下游应用向 MQ 组件自动发送 ACK 确认消息被消费
-
下游应用通知可靠消息系统消息被成功消费,可靠消息将该消息状态更改为已完成
3、TCC
第一阶段:主业务服务分别调用所有从业务服务的 try 操作,并在活动管理器中记录所有从业务服务。当所有从业务服务 try 成功或者某个从业务服务 try 失败时,进入第二阶段。
第二阶段:活动管理器根据第一阶段从业务服务的 try 结果来执行 confirm 或 cancel 操作。如果第一阶段所有从业务服务都 try 成功,则协作者调用所有从业务服务的 confirm 操作,否则,调用所有从业务服务的 cancel 操作。
在第二阶段中,confirm 和 cancel 同样存在失败情况,所以需要对这两种情况做 异常处理 以保证数据一致性。
-
Confirm 失败:则回滚所有 confirm 操作并执行 cancel 操作。
-
Cancel 失败:从业务服务需要提供自动 cancel 机制,以保证 cancel 成功。
目前有很多基于 RPC 的 TCC 框架,但是不适用于微服务架构下基于 HTTP 协议的交互模式
5、最大努力通知型
上游应用,发消息到MQ队列
下游应用,接受请求,并返回通知结果
最大努力通知服务,监听消息队列,将消息存储到数据库中,并按照规则调用下游应用的发送通知接口