|
CAP 原则
CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
CAP原则的精髓就是要么AP,要么CP,要么AC,但是不存在CAP。如果在某个分布式系统中数据无副本, 那么系统必然满足强一致性条件, 因为只有独一数据,不会出现数据不一致的情况,此时C和P两要素具备,但是如果系统发生了网络分区状况或者宕机,必然导致某些数据不可以访问,此时可用性条件就不能被满足,即在此情况下获得了CP系统,但是CAP不可同时满足。
回顾:
DotNetCore.CAP
CAP 是一个在分布式系统中(SOA,MicroService)实现事件总线及最终一致性(分布式事务)的一个开源的 C# 库,她具有轻量级,高性能,易使用等特点。
GitHub地址:https://github.com/dotnetcore/CAP
Dotnet CAP 具有 Event Bus 的所有功能,并且CAP提供了更加简化的方式来处理EventBus中的发布/订阅。
架构预览
CAP 支持 Kafka、RabbitMQ、AzureServiceBus、AmazonSQS 等消息队列,CAP 提供了 Sql Server, MySql, PostgreSQL,MongoDB 的扩展作为数据库存储。
本文使用 RabbitMQ 和 SQL Server 作为消息队列和存储。
安装 RabbitMQ
具体安装教程略,请参考:
添加账户也略,请参考:
我自己添加了 test 账户和 cap Virtual Hosts,如下图:
否则会报错如下:
ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
None of the specified endpoints were reachable
.NET Core 集成 CAP
首先,新建一个 ASP.NET Core 项目,它既是发送端又是接收端。使用 nuget 命令安装如下包:
在 startup 配置服务方法 ConfigureServices 配置如下:
可以访问网站 /cap 地址,查看仪表盘,如下图:
数据持久化:Cap 会自动创建 "Published"、"Received" 两个本地数据库表
CREATE TABLE [cap].[Published](
[Id] [bigint] NOT NULL,
[Version] [nvarchar](20) NOT NULL,
[Name] [nvarchar](200) NOT NULL,
[Content] [nvarchar](max) NULL,
[Retries] [int] NOT NULL,
[Added] [datetime2](7) NOT NULL,
[ExpiresAt] [datetime2](7) NULL,
[StatusName] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_cap.Published] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO CREATE TABLE [cap].[Received](
[Id] [bigint] NOT NULL,
[Version] [nvarchar](20) NOT NULL,
[Name] [nvarchar](200) NOT NULL,
[Group] [nvarchar](200) NULL,
[Content] [nvarchar](max) NULL,
[Retries] [int] NOT NULL,
[Added] [datetime2](7) NOT NULL,
[ExpiresAt] [datetime2](7) NULL,
[StatusName] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_cap.Received] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
HomeController 控制器方法如下:
当用户注册成功后,会发送3条不同主题的消息,然后由订阅者去消费。
当CAP启动的时候,它将创建一个默认的消费者组,如果多个相同消费者组的消费者消费同一个Topic消息的时候,只会有一个消费者被执行。 相反,如果消费者都位于不同的消费者组,则所有的消费者都会被执行。
新建一个 .NET Core 的控制台项目,作为订阅端(消费端),还是引用刚才的包,仪表盘可以忽略。
如果是在Controller中,直接添加[CapSubscribe("")] 来订阅相关消息。
如果你的方法没有位于Controller 中,那么你订阅的类需要继承 ICapSubscribe,然后添加[CapSubscribe("")]标记。
代码如下:
开启订阅客户端,尝试访问 http://localhost:28116/Home/UserRegister 发送消息,效果图如下:
控制台和控制器的接收端都触发了,如下图:
尝试在接收消息方法手动抛出异常,代码如下:
cap 会帮我们自动重试该方法,失败后的重试次数,默认50次,失败后的重拾间隔,默认60秒,如下图:
框架无法做到100%确保消息只执行一次,所以在一些关键场景消息端在方法实现的过程中自己注意业务去重。
最后,附上源码:
|
上一篇:CSV 在线转换 Markdown 语法下一篇:HttpClient 直接 POST 发送 byte 字节(gzip)压缩请求
|