使用Cap解决.Netcore分布式事务
一、什么是Cap
CAP 是一个基于 .NET Standard 的 C# 库,它是一种处理分布式事务的解决方案,同样具有 EventBus 的功能,它具有轻量级、易使用、高性能等特点。
在我们构建 SOA 或者 微服务系统的过程中,我们通常需要使用事件来对各个服务进行集成,在这过程中简单的使用消息队列并不能保证数据的最终一致性, CAP 采用的是和当前数据库集成的本地消息表的方案来解决在分布式系统互相调用的各个环节可能出现的异常,它能够保证任何情况下事件消息都是不会丢失的。
你同样可以把 CAP 当做 EventBus 来使用,CAP提供了一种更加简单的方式来实现事件消息的发布和订阅,在订阅以及发布的过程中,你不需要继承或实现任何接口。
以下是CAP集在ASP.NET Core 微服务架构中的一个示意图:
二、安装
你可以运行以下下命令在你的项目中安装 CAP。
PM> Install-Package DotNetCore.CAP
CAP 支持 Kafka、RabbitMQ、AzureServiceBus 等消息队列,你可以按需选择下面的包进行安装:
PM> Install-Package DotNetCore.CAP.Kafka
PM> Install-Package DotNetCore.CAP.RabbitMQ
PM> Install-Package DotNetCore.CAP.AzureServiceBus
我们这里采用RabbitMQ,安装教程请转到另一篇文章:Winows下安装RabbitMQ
CAP 提供了 Sql Server, MySql, PostgreSQL,MongoDB 的扩展作为数据库存储:
// 按需选择安装你正在使用的数据库
PM> Install-Package DotNetCore.CAP.SqlServer
PM> Install-Package DotNetCore.CAP.MySql
PM> Install-Package DotNetCore.CAP.PostgreSql
PM> Install-Package DotNetCore.CAP.MongoDB
我们这里采用SqlServer
三、配置
首先配置CAP到 Startup.cs 文件中,如下:
public void ConfigureServices(IServiceCollection services)
{
...... services.AddDbContext<AppDbContext>(); services.AddCap(x =>
{
//如果你使用的 EF 进行数据操作,你需要添加如下配置:
x.UseEntityFramework<AppDbContext>(); //可选项,你不需要再次配置 x.UseSqlServer 了 //如果你使用的ADO.NET,根据数据库选择进行配置:
x.UseSqlServer("数据库连接字符串");
x.UseMySql("数据库连接字符串");
x.UsePostgreSql("数据库连接字符串"); //如果你使用的 MongoDB,你可以添加如下配置:
x.UseMongoDB("ConnectionStrings"); //注意,仅支持MongoDB 4.0+集群 //CAP支持 RabbitMQ、Kafka、AzureServiceBus 等作为MQ,根据使用选择配置:
x.UseRabbitMQ("ConnectionStrings");
x.UseKafka("ConnectionStrings");
x.UseAzureServiceBus("ConnectionStrings");
});
}
我们这里采用EF数据库配置和RabbitMQ如下:
services.AddCap(x =>
{
//如果你使用的 EF 进行数据操作,你需要添加如下配置:
x.UseEntityFramework<SysContext>(); x.UseRabbitMQ("localhost"); });
四、启动
运行程序,将在数据库生成Cap.Published和Cap.Received表如下图所示:

五、发布和订阅
在 Controller 中注入 ICapPublisher 然后使用 ICapPublisher 进行消息发送
private readonly ICapPublisher _capBus;
public ValuesController(ICapPublisher capPublisher)
{
_capBus = capPublisher;
}
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
_capBus.Publish("xxx.services.show.time", DateTime.Now);
return new string[] { "value1", "value2" };
}
[CapSubscribe("xxx.services.show.time")]
public void ShowTime(DateTime datetime)
{
}
运行程序,Cap.Published和Cap.Received将生成发布消息和订阅消息的记录
如果你的订阅方法没有位于 Controller 中,则你订阅的类需要继承 ICapSubscribe:
namespace xxx.Service
{
public interface ISubscriberService
{
public void CheckReceivedMessage(DateTime datetime);
} public class SubscriberService: ISubscriberService, ICapSubscribe
{
[CapSubscribe("xxx.services.show.time")]
public void CheckReceivedMessage(DateTime datetime)
{
}
}
}
然后在 Startup.cs 中的 ConfigureServices() 中注入你的 ISubscriberService 类
public void ConfigureServices(IServiceCollection services)
{
//注意: 注入的服务需要在 `services.AddCap()` 之前
services.AddTransient<ISubscriberService,SubscriberService>(); services.AddCap(x=>{});
}
六、订阅者组
订阅者组的概念类似于 Kafka 中的消费者组,它和消息队列中的广播模式相同,用来处理不同微服务实例之间同时消费相同的消息。
当CAP启动的时候,她将创建一个默认的消费者组,如果多个相同消费者组的消费者消费同一个Topic消息的时候,只会有一个消费者被执行。 相反,如果消费者都位于不同的消费者组,则所有的消费者都会被执行。
相同的实例中,你可以通过下面的方式来指定他们位于不同的消费者组。
[CapSubscribe("xxx.services.show.time", Group = "group1" )]
public void ShowTime1(DateTime datetime)
{
}
[CapSubscribe("xxx.services.show.time", Group = "group2")]
public void ShowTime2(DateTime datetime)
{
}
ShowTime1 和 ShowTime2 处于不同的组,他们将会被同时调用。
PS,你可以通过下面的方式来指定默认的消费者组名称:
services.AddCap(x =>
{
x.DefaultGroup = "default-group-name";
});
七、Dashboard
CAP 2.1+ 以上版本中提供了仪表盘(Dashboard)功能,你可以很方便的查看发出和接收到的消息。除此之外,你还可以在仪表盘中实时查看发送或者接收到的消息。
在分布式环境中,仪表盘内置集成了 Consul 作为节点的注册发现,同时实现了网关代理功能,你同样可以方便的查看本节点或者其他节点的数据,它就像你访问本地资源一样。
services.AddCap(x =>
{
//... // 注册 Dashboard
x.UseDashboard(); // 注册节点到 Consul
x.UseDiscovery(d =>
{
d.DiscoveryServerHostName = "localhost";
d.DiscoveryServerPort = ;
d.CurrentNodeHostName = "localhost";
d.CurrentNodePort = ;
d.NodeId = ;
d.NodeName = "CAP No.1 Node";
});
});
仪表盘默认的访问地址是:http://localhost:xxx/cap,你可以在d.MatchPath配置项中修改cap路径后缀为其他的名字。
参考资料:https://github.com/dotnetcore/CAP/blob/master/README.zh-cn.md
使用Cap解决.Netcore分布式事务的更多相关文章
- CAP理论与分布式事务解决方案
微服务系统所设计的系统是分布式系统.分布式系统有一个著名的CAP理论,即同时满足"一致性""可用性"和"分区容错"是一件不可能的事.CAP理 ...
- cap理论与分布式事务的解决方案
现在很火的微服务架构所设计的系统是分布式系统.分布式系统有一个著名的CAP理论,即一个分布式系统要同时满足一致性(Consistency).可用性(Availablility)和分区容错(Partit ...
- .netcore 分布式事务CAP2.6之控制台使用
上一编讲了cap2.6的快速入门,这次我们来讲讲在控制台中如何使用cap2.6.因为cap2.6的内存模式目前已经可以使用了,相关组件已经更新,所以这次我们以简单的内存模式为例. 1:创建项目 创建一 ...
- .NET Core 事件总线,分布式事务解决方案:CAP
背景 相信前面几篇关于微服务的文章也介绍了那么多了,在构建微服务的过程中确实需要这么一个东西,即便不是在构建微服务,那么在构建分布式应用的过程中也会遇到分布式事务的问题,那么 CAP 就是在这样的背景 ...
- .NET Core 事件总线,分布式事务解决方案:CAP 基于Kafka
背景 相信前面几篇关于微服务的文章也介绍了那么多了,在构建微服务的过程中确实需要这么一个东西,即便不是在构建微服务,那么在构建分布式应用的过程中也会遇到分布式事务的问题,那么 CAP 就是在这样的背景 ...
- 【转】.NET Core 事件总线,分布式事务解决方案:CAP
[转].NET Core 事件总线,分布式事务解决方案:CAP 背景 相信前面几篇关于微服务的文章也介绍了那么多了,在构建微服务的过程中确实需要这么一个东西,即便不是在构建微服务,那么在构建分布式应用 ...
- LCN解决分布式事务原理解析+项目实战(原创精华版)
写在前面: 原创不易,如果觉得不错推荐一下,谢谢! 由于工作需要,公司的微服务项目需解决分布式事务的问题,且由我进行分布式事务框架搭建和整合工作. 那么借此机会好好的将解决分布式事务的内容进行整理一下 ...
- 一文教你迅速解决分布式事务 XA 一致性问题
欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:腾讯云数据库团队 近日,腾讯云发布了分布式数据库解决方案(DCDB),其最明显的特性之一就是提供了高于开源分布式事务XA的性能.大型 ...
- asp.net core集成CAP(分布式事务总线)
一.前言 感谢杨晓东大佬为社区贡献的CAP开源项目,传送门在此:.NET Core 事件总线,分布式事务解决方案:CAP 以及 如何在你的项目中集成 CAP[手把手视频教程],之前也在工作中遇到分布式 ...
随机推荐
- C#开发命令执行驱动程序 之 读入命令行参数
/// <summary> /// 在cmd窗体内执行如下: /// OrderDriverApp.exe Order Driver App /// 返回: /// The args ar ...
- 运营的Python指南 - Python 操作Excel
这是一份写给运营人员的Python指南.本文主要讲述如何使用Python操作Excel.完成Excel的创建,查询和修改操作. 相关代码请参考 https://github.com/RustFishe ...
- Java 8 - 行为参数化
前言: 以下内容来源于java8实战一书,我将里面学习的内容做一个整理,方便没空读书的小伙伴快速入门实战java8 正文: 假设一个果农收获了一园的苹果,他需要你根据他的条件筛选出满意的苹果 首先我们 ...
- MIT线性代数:22.对角化和A的幂
- android内嵌H5页(webview)如何定位
一.切换至webview后再定位元素 (1)获取页面上下文 contexts = driver.contexts (2)切换至webview driver.switch_to.context(cont ...
- noip模拟9 达哥随单题
T1.随 看题第一眼,就瞄到最下面 孙金宁教你学数学 ?????原根?目测神题,果断跳过. 最后打了个快速幂,愉快的收到了达哥送来的10分. 实际上这题暴力不难想,看到一个非常小的mod应该就能想到 ...
- 苹果审核ipv6海外解决思路-About APP Store
原始简书文章地址(也是我自己的) 首先声明,一我不负责涉及你们内部服务器. 二是好好读文章,别人能过,你们也能过 苹果6月1日出的IPV6协议阻碍了国内大多数积极开发者,我司也不外乎,经过三次被拒后, ...
- 腾讯正式开源图计算框架Plato,十亿级节点图计算进入分钟级时代
腾讯开源再次迎来重磅项目,14日,腾讯正式宣布开源高性能图计算框架Plato,这是在短短一周之内,开源的第五个重大项目. 相对于目前全球范围内其它的图计算框架,Plato可满足十亿级节点的超大规模图计 ...
- python——namedtuple
namedtuple()概念理解分享 我们都知道元组tuple的概念,tuple是一个定义之后就不能够更改的可迭代对象,namedtuple作为tuple的兄弟具有同样的属性,一旦定义就不可以更改.但 ...
- vmware centos共享文件夹
vmware centos共享文件夹 查看VMware Tools 是否安装成功 <pre>vmware-hgfsclient</pre> 出现共享文件夹<pre> ...