一、什么是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分布式事务的更多相关文章

  1. CAP理论与分布式事务解决方案

    微服务系统所设计的系统是分布式系统.分布式系统有一个著名的CAP理论,即同时满足"一致性""可用性"和"分区容错"是一件不可能的事.CAP理 ...

  2. cap理论与分布式事务的解决方案

    现在很火的微服务架构所设计的系统是分布式系统.分布式系统有一个著名的CAP理论,即一个分布式系统要同时满足一致性(Consistency).可用性(Availablility)和分区容错(Partit ...

  3. .netcore 分布式事务CAP2.6之控制台使用

    上一编讲了cap2.6的快速入门,这次我们来讲讲在控制台中如何使用cap2.6.因为cap2.6的内存模式目前已经可以使用了,相关组件已经更新,所以这次我们以简单的内存模式为例. 1:创建项目 创建一 ...

  4. .NET Core 事件总线,分布式事务解决方案:CAP

    背景 相信前面几篇关于微服务的文章也介绍了那么多了,在构建微服务的过程中确实需要这么一个东西,即便不是在构建微服务,那么在构建分布式应用的过程中也会遇到分布式事务的问题,那么 CAP 就是在这样的背景 ...

  5. .NET Core 事件总线,分布式事务解决方案:CAP 基于Kafka

    背景 相信前面几篇关于微服务的文章也介绍了那么多了,在构建微服务的过程中确实需要这么一个东西,即便不是在构建微服务,那么在构建分布式应用的过程中也会遇到分布式事务的问题,那么 CAP 就是在这样的背景 ...

  6. 【转】.NET Core 事件总线,分布式事务解决方案:CAP

    [转].NET Core 事件总线,分布式事务解决方案:CAP 背景 相信前面几篇关于微服务的文章也介绍了那么多了,在构建微服务的过程中确实需要这么一个东西,即便不是在构建微服务,那么在构建分布式应用 ...

  7. LCN解决分布式事务原理解析+项目实战(原创精华版)

    写在前面: 原创不易,如果觉得不错推荐一下,谢谢! 由于工作需要,公司的微服务项目需解决分布式事务的问题,且由我进行分布式事务框架搭建和整合工作. 那么借此机会好好的将解决分布式事务的内容进行整理一下 ...

  8. 一文教你迅速解决分布式事务 XA 一致性问题

    欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:腾讯云数据库团队 近日,腾讯云发布了分布式数据库解决方案(DCDB),其最明显的特性之一就是提供了高于开源分布式事务XA的性能.大型 ...

  9. asp.net core集成CAP(分布式事务总线)

    一.前言 感谢杨晓东大佬为社区贡献的CAP开源项目,传送门在此:.NET Core 事件总线,分布式事务解决方案:CAP 以及 如何在你的项目中集成 CAP[手把手视频教程],之前也在工作中遇到分布式 ...

随机推荐

  1. linux IMX6 汇编点亮一个LED灯

    驱动Linux引脚与驱动STM32其实是一样的,都是在操作寄存器,在相应的寄存器上附上相应的值即可驱动. IMX6U手册上有各个管脚的命名,跟STM32不同,IOMUXC_SW_MUC_CTL_PAD ...

  2. Access教程 Access学习 Access培训 Access QQ交流集中地

    Access教程 Access学习 Access培训 Access QQ交流集中地 http://www.office-cn.net/plugin.php?id=zstm_qqgroup:index ...

  3. PowerBI开发 第十六篇:PowerBI Service基本概念

    从总体上来看,PowerBI Service 有4个主要的构建模块,分别是dashboards.reports.workbooks 和 datasets,这四个模块都是目录,位于workspaces目 ...

  4. IndentationError: unindent does not match any outer indentation level笔记

    执行一个Python脚本的时候,报"IndentationError: unindent does not match any outer indentation level" 错 ...

  5. nginx篇中级用法之反向代理(七层调度)

    环境: 两台后端web,一台代理服务器 web1:eth0:192.168.2.100/24   httpd做一个web web2:eth0:192.168.2.200/24   httpd做一个we ...

  6. 差异:后缀数组(wzz模板理解),单调栈

    因为涉及到对模板的理解,所以就着代码看会好一些. 让那些坚决不颓代码的人受委屈了. 我是对着wzz的板子默写的,可能不完全一样啊. 还有代码注释里都是我个人的理解,不保证正确,但欢迎指正. 可以有选择 ...

  7. 使用Typescript重构axios(二十七)——添加请求状态码合法性校验

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  8. C语言中的可变参数-printf的实现原理

    C语言中的可变参数-printf的实现原理 在C/C++中,对函数参数的扫描是从后向前的.C/C++的函数参数是通过压入堆栈的方式来给函数传参数的(堆栈是一种先进后出的数据结构),最先压入的参数最后出 ...

  9. dubbo中出现can not be invoked any more

    具体错误示例如下 从错误看,是客户方发起调用时,dubbo会去检查本地的invoker instance,如果发现invoker已经是destroy status,则直接抛出上面的异常,下面先来说下平 ...

  10. Material for oauth 2

    oauth 2 in 8 steps:  https://knpuniversity.com/screencast/oauth Live demo of oauth 2 (with server im ...