services.AddCap(capOptions => { capOptions.UseKafka(kafkaOption=>{ // kafka options. // kafkaOptions.MainConfig.Add("", ""); }); });
KafkaOptions 提供了有关 Kafka 相关的配置,由于Kafka的配置比较多,所以此处使用的是提供的 MainConfig 字典来支持进行自定义配置,你可以查看这里来获取对配置项的支持信息。
https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md
3.4 SqlServer Options如果你使用的是 EntityFramewrok,你用不到该配置项下的内容。
CAP 采用的是针对 CapOptions 进行扩展来实现 SqlServer 的配置功能,所以针对 SqlServer 的配置用法如下:
services.AddCap(capOptions => { capOptions.UseSqlServer(sqlserverOptions => { // sqlserverOptions.ConnectionString }); });
NAME DESCRIPTION TYPE DEFAULT
Schema Cap表架构 string Cap
ConnectionString 数据库连接字符串 string null
3.5 MySql Options如果你使用的是 EntityFramewrok,你用不到该配置项下的内容。
CAP 采用的是针对 CapOptions 进行扩展来实现 MySql 的配置功能,所以针对 MySql 的配置用法如下:
services.AddCap(capOptions => { capOptions.UseMySql(mysqlOptions => { // mysqlOptions.ConnectionString }); });
NAME DESCRIPTION TYPE DEFAULT
TableNamePrefix Cap表名前缀 string cap
ConnectionString 数据库连接字符串 string null
4、设计原理 4.1 动机随着微服务架构的流行,越来越多的人在尝试使用微服务来架构他们的系统,而在这其中我们会遇到例如分布式事务的问题,为了解决这些问题,我没有发现简单并且易于使用的解决方案,所以我决定来打造这样一个库来解决这个问题。
最初 CAP 是为了解决分布式系统中的事务问题,她采用的是 异步确保 这种机制实现了分布式事务的最终一致性,更多这方面的信息可以查看第6节。
现在 CAP 除了解决分布式事务的问题外,她另外一个重要的功能就是作为 EventBus 来使用,她具有 EventBus 的所有功能,并且提供了更加简化的方式来处理EventBus中的发布/订阅。
4.2 持久化CAP 依靠本地数据库实现消息的持久化,CAP 使用这种方式来应对一切环境或者网络异常导致消息丢失的情况,消息的可靠性是分布式事务的基石,所以在任何情况下消息都不能丢失。
对于消息的持久化分为两种:
① 消息进入消息队列之前的持久化
在消息进入到消息队列之前,CAP使用本地数据库表对消息进行持久化,这样可以保证当消息队列出现异常或者网络错误时候消息是没有丢失的。
为了保证这种机制的可靠性,CAP使用和业务代码相同的数据库事务来保证业务操作和CAP的消息在持久化的过程中是强一致的。也就是说在进行消息持久化的过程中,任何一方发生异常情况数据库都会进行回滚操作。
② 消息进入到消息队列之后的持久化
消息进入到消息队列之后,CAP会启动消息队列的持久化功能,我们需要说明一下在 RabbitMQ 和 Kafka 中CAP的消息是如何持久化的。
针对于 RabbitMQ 中的消息持久化,CAP 使用的是具有消息持久化功能的消费者队列,但是这里面可能有例外情况,参加 2.2.1 章节。
由于 Kafka 天生设计的就是使用文件进行的消息持久化,在所以在消息进入到Kafka之后,Kafka会保证消息能够正确被持久化而不丢失。
4.3 通讯数据流CAP 中消息的流转过程大致如下:
“ P ” 代表消息发送者(生产者)。 “ C ” 代表消息消费者(订阅者)。
4.4 一致性CAP 采用最终一致性作为的一致性方案,此方案是遵循 CAP 理论,以下是CAP理论的描述。
C(一致性)一致性是指数据的原子性,在经典的数据库中通过事务来保障,事务完成时,无论成功或回滚,数据都会处于一致的状态,在分布式环境下,一致性是指多个节点数据是否一致;
A(可用性)服务一直保持可用的状态,当用户发出一个请求,服务能在一定的时间内返回结果;
P(分区容忍性)在分布式应用中,可能因为一些分布式的原因导致系统无法运转,好的分区容忍性,使应用虽然是一个分布式系统,但是好像一个可以正常运转的整体
根据 “CAP”分布式理论, 在一个分布式系统中,我们往往为了可用性和分区容错性,忍痛放弃强一致支持,转而追求最终一致性。大部分业务场景下,我们是可以接受短暂的不一致的。
第 6 节将对此做进一步介绍。
5、实现CAP 封装了在 ASP.NET Core 中的使用依赖注入来获取 Publisher (ICapPublisher)的接口。而启动方式类似于 “中间件” 的形式,通过在 Startup.cs 配置 ConfigureServices 和 Configure 进行启动。
5.1 消息表当系统引入CAP之后并首次启动后,CAP会在客户端生成 3 个表,分别是 Cap.Published, Cap.Received, Cap.Queue。注意表名可能在不同的数据库具有不同的大小写区分,如果你在运行项目的时候没有显式的指定数据库生成架构(SQL Server)或者表名前缀(MySql)的话,默认情况下就是以上3个名字。
Cap.Published:这个表主要是用来存储 CAP 发送到MQ(Message Queue)的客户端消息,也就是说你使用 ICapPublisher 接口 Publish 的消息内容。
Cap.Received:这个表主要是用来存储 CAP 接收到 MQ(Message Queue) 的客户端订阅的消息,也就是使用 CapSubscribe[] 订阅的那些消息。
Cap.Queue: 这个表主要是CAP内部用来处理发送和接收消息的一个临时表,通常情况下,如果系统不出现问题,这个表将是空的。