CAP 理论
在分布式环境中,C(Consistency)一致性 A (Avaliability) 可用性 P(Partition Tolerance) 分区容错 是不能同时满足的。
分区容错 【Partition Tolerance】
ServerA(上海1)在访问 ServerB(北京1)的时候可能出现 网络瘫痪 服务故障等原因,导致之间无妨访问。
一致性 【Avaliability】
下面是银行模拟转账业务,用户A(工商银行) 给 用户B(中国银行) 发起一笔转账业务 100元, 用户A调用
工商银行(ServiceA)-100元,在调用 中国银行(ServiceB)给用户B +100,由于ServiceA 调用ServiceB有延时,这时候用户A账号已经少了100元,但是由于延时原因,用户B在立马查询的时候发现账号此刻并未到账100元。
这个场景在 用户提现,支付宝提现,提示2小时到账
Partition Tolerance 【可用性】 收到请求必须相应
同样还是上面银行转账的例子,用户A在工商银行系统-100,在中国银行给用户B加100的操作中,如果要保证用户B已经收到了100元才能查询,那么次数可以把 这个整个操作当做一个整体,只有全部完成的时候才能够对外提供服务。这时候就牺牲了可用性。
所以在分布式环境中,CAP是不能够同时满足的。至于是选择CA CP AP,根据自己的业务需求
在银行系统中, 一致性最重要,数据不能错,CP
在微服务中,系统的可用性,尤其是分布式,可用性尤为重要,没有可用性是跑不起来的 AP
一致性的探究
强一致性
任意时刻数据都是一致性的 2PC 3PC
2PC (two-phase commit protocol)
1 性能问题
2 单点故障—事务管理器
3 消息丢失问题
只是解决小范围,或者强制要求一致性,所以就
没有可用性
SQLServer+DTC—局限在Windows+.NET
Framework,.NET Core目前没有解决方案
MySQL--XA协议—也没有DTC这种协调器,是
需要用代码实现XA,实现强事务--.NETCore也
没有---因为确实在分布式下用的少
3PC(three-phase commit protocol)
Ready-GO!
CanCommit—PreCommit--DoCommit
3PC只是数据库可以自动提交,避免调度
者超时问题,但是其他还在的,
1 性能问题
2 单点故障—事务管理器
3 消息丢失问题
弱一致性 TCC(Try-Confirm-Cancel)
允许某一时刻不一致,承诺在一定时间内变成一致的 Try-Confirm-Cancel 代码层面--Saga
TCC的注意点
1 分段设计:try成功 就一定能Confirm
2 允许空回滚:重复cancel不能错
3 悬挂控制:try阻塞,先cancel,保证数据正确
4 幂等控制:TCC多少次,结果不变
5 可见控制:值的展示
5 并发访问控制
主要用在银行、阿里---钱必须保障-不能阻塞—设计负责,开发工作重
ByteTCC、Himly、TCC-transaction事务管理器—这些都是Java的 .NET
没有—所以解决方案也没有—除非自己写
最终一致性 (BASE理论)
—允许数据不一致,但是最终最终,数据还是得一致的 业务层面
Base理论:
1. Basically Available(基本可用)
2. (最终一致性)
3. Soft state(软状态)
4. Eventually consistent
微服务架构里面,可用性是最重要的
思想是最重要,指引方向
本地消息表分布式事务
MQ分布式事务--本地消息表--基于消息的一致性
上游投递消息
下游获取消息
上游投递稳定性
下游接受稳定性
上游投递消息稳定性
如何保证数据一定能写入到队列,只有保障了投递的稳定性,才能保障流程的正常。
上层应用在操作订单服务的时候,先将数据写入到临时数据表 Publisher中,另外一部分处理业务逻辑,这部分是一个事务。Publisher表中有一些软状态,成功和失败。表示是否成功写入到消息队列中。
队列数据可靠性
如何保证队列数据不丢失?RabbitMQ—集群&持久化
下游获取消息稳定性
如何保证下游一定获取到数据?Ack 就够了吗?
库存服务通过消息队列中拿到上游给的信息,但同时也有可能失败,比如库存服务宕机,或是网络超时等原因,这时候理应有从试、过期等机制,拿到数据后ACK将数据从消息队列中移除,避免消息队列有脏数据。
NCC CAP框架
CAP成熟的开源框架,完整实现了全套特性 使用最终一致性
.NET Core中安装使用安装。
DotNetCore.CAP 核心组件
DotNetCore.CAP.SqlServer 业务处理数据库
DotNetCore.CAP.RabbitMQ 消息队列 下游应用通过消息队列拿到上游应用传递的参数
DotNetCore.CAP.MongoDB 业务处理数据库
该组件可以支持多种数据库. git 地址:https://github.com/dotnetcore/CAP
PM> Install-Package DotNetCore.CAP.Kafka
PM> Install-Package DotNetCore.CAP.RabbitMQ
PM> Install-Package DotNetCore.CAP.AzureServiceBus
PM> Install-Package DotNetCore.CAP.AmazonSQS
PM> Install-Package DotNetCore.CAP.NATS
PM> Install-Package DotNetCore.CAP.RedisStreams
PM> Install-Package DotNetCore.CAP.Pulsar
框架简单使用案例: