CAP-分布式事务的解决方案

CAP 是一个基于 .NET Standard 的 C# 库,它是一种处理分布式事务的解决方案,同样具有 EventBus 的功能,它具有轻量级、易使用、高性能等特点。

https://github.com/dotnetcore/CAP

在我们构建 SOA 或者 微服务系统的过程中,我们通常需要使用事件来对各个服务进行集成,在这过程中简单的使用消息队列并不能保证数据的最终一致性, CAP 采用的是和当前数据库集成的本地消息表的方案来解决在分布式系统互相调用的各个环节可能出现的异常,它能够保证任何情况下事件消息都是不会丢失的。

你同样可以把 CAP 当做 EventBus 来使用,CAP提供了一种更加简单的方式来实现事件消息的发布和订阅,在订阅以及发布的过程中,你不需要继承或实现任何接口。

这是CAP集在ASP.NET Core 微服务架构中的一个示意图:

架构预览

CAP 实现了 eShop 电子书 中描述的发件箱模式

Getting Started

NuGet

你可以运行以下下命令在你的项目中安装 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

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

Configuration

首先配置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");});
}

发布

在 Controller 中注入 ICapPublisher 然后使用 ICapPublisher 进行消息发送

public class PublishController : Controller
{private readonly ICapPublisher _capBus;public PublishController(ICapPublisher capPublisher){_capBus = capPublisher;}//不使用事务[Route("~/without/transaction")]public IActionResult WithoutTransaction(){_capBus.Publish("xxx.services.show.time", DateTime.Now);return Ok();}//Ado.Net 中使用事务,自动提交[Route("~/adonet/transaction")]public IActionResult AdonetWithTransaction(){using (var connection = new MySqlConnection(ConnectionString)){using (var transaction = connection.BeginTransaction(_capBus, autoCommit: true)){//业务代码_capBus.Publish("xxx.services.show.time", DateTime.Now);}}return Ok();}//EntityFramework 中使用事务,自动提交[Route("~/ef/transaction")]public IActionResult EntityFrameworkWithTransaction([FromServices]AppDbContext dbContext){using (var trans = dbContext.Database.BeginTransaction(_capBus, autoCommit: true)){//业务代码_capBus.Publish("xxx.services.show.time", DateTime.Now);}return Ok();}
}

订阅

Action Method

在 Action 上添加 CapSubscribeAttribute 来订阅相关消息。

public class PublishController : Controller
{[CapSubscribe("xxx.services.show.time")]public void CheckReceivedMessage(DateTime datetime){Console.WriteLine(datetime);}
}

Service Method

如果你的订阅方法没有位于 Controller 中,则你订阅的类需要继承 ICapSubscribe

namespace xxx.Service
{public interface ISubscriberService{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)功能,你可以很方便的查看发出和接收到的消息。除此之外,你还可以在仪表盘中实时查看发送或者接收到的消息。

使用一下命令安装 Dashboard:

PM> Install-Package DotNetCore.CAP.Dashboard

在分布式环境中,仪表盘内置集成了 Consul 作为节点的注册发现,同时实现了网关代理功能,你同样可以方便的查看本节点或者其他节点的数据,它就像你访问本地资源一样。

services.AddCap(x =>
{//...// 注册 Dashboardx.UseDashboard();// 注册节点到 Consulx.UseDiscovery(d =>{d.DiscoveryServerHostName = "localhost";d.DiscoveryServerPort = 8500;d.CurrentNodeHostName = "localhost";d.CurrentNodePort = 5800;d.NodeId = 1;d.NodeName = "CAP No.1 Node";});
});

仪表盘默认的访问地址是:http://localhost:xxx/cap,你可以在d.MatchPath配置项中修改cap路径后缀为其他的名字。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/303321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 初始二维数组长度,php二维数组排序与默认自然排序的方法介绍

php二维数组排序函数&#xff0c;默认自然排序&#xff0c;即sort排序。这里可以指定按二维数组中的某个值进行多种方法排序&#xff0c;具体看下面的程序注释。 代码如下:/*** function 二维数组自然排序* author www.phpernote.com* param array $array 需要排序的数组(二维)…

做操作系统的公司,为什么不能把系统安全做好?

易用和安全&#xff0c;从来都是一对矛盾&#xff0c;过分考虑方便用户操作&#xff0c;就很容易带来系统隐患。向上兼容也会带来系统的复杂性&#xff0c;复杂的系统漏洞一定多。对微软来说&#xff0c;它的每一个版本&#xff0c;都需要考虑向下兼容&#xff0c;比如Win95是3…

我是怎么用机器学习技术找到女票的

机器学习在我们生活中的用处有多大&#xff0c;就不用我们多说了&#xff0c;大到医疗诊断&#xff0c;小到手机应用&#xff0c;机器学习都应用的风风火火。但是用机器学习帮自己在学校找对象&#xff0c;你听说过吗?最近滑铁卢大学一位叫 Bai Li 的留学生(李白?应是中国同胞…

.Net5 WPF快速入门系列教程

一、概要在工作中大家会遇到需要学习新的技术或者临时被抽调到新的项目当中进行开发。通常这样的情况比较紧急没有那么多的时间去看书学习。所以这里向wpf技术栈的开发者分享一套wpf教程&#xff0c;基于.net5框架进行开发本系列每一期视频长度平均在15分钟左右&#xff0c;并利…

php 重定向数据不丢失,PHP重定向如何实现数据不丢失?

PHP重定向如何实现数据不丢失&#xff1f;首先获取要保存的数据&#xff1b;$data [username > guanhuicoder,redirect_url > ./index.phpemail > guanhuicodercode.com];然后将数据转为JSON字符串&#xff0c;并将其储存在Session中&#xff1b;$data [username &g…

数据“被”覆盖有假象,SQL数据库恢复终极绝招(数据恢复高级技术)

很多数据恢复工程师包括一些数据恢复技术爱好者经常会问同样一个问题&#xff1a;“数据一旦被覆盖了&#xff0c;还能不能恢复呀&#xff1f;我听说国外能恢复被覆盖以后的数据&#xff0c;据说只要是覆盖操作在7次以内&#xff0c;都能恢复出来&#xff0c;国内有没有这种技术…

北大教授郑也夫斗胆谈了7个天大的问题(非常狠,也很现实)

我是一个小人物&#xff0c;今天斗胆谈一个天大的问题——中国教育。中国教育是一个天大的问题&#xff0c;不是说我们有多大的本领把它办得多么好&#xff0c;而是我们居然可以把它办得这样糟&#xff0c;这是一个很沉痛的话题。——北大教授、社会学家郑也夫1不输在起跑线&am…

.NET 6 Preview 3 中 ASP.NET Core 的更新和改进

原文&#xff1a;bit.ly/2Qb56NP作者&#xff1a;Daniel Roth译者&#xff1a;精致码农-王亮.NET 6 预览版 3 现已推出&#xff0c;其中包括许多对新的 ASP.NET Core 改进。以下是本次预览版的新内容&#xff1a;更小的 SignalR、Blazor Server、MessagePack 脚本文件启用 Redi…

php 图片消除锯齿,ps如何消除边缘锯齿

PS消除边缘锯齿的方法&#xff1a;打开图片选择魔棒工具&#xff0c;在窗口中解锁图层然后将鼠标移动到背景区域&#xff0c;左键单击它再按删除键&#xff0c;然后再右键点击人像&#xff0c;选择羽化&#xff0c;将羽化半径设置为4&#xff0c;点击确定后按删除键&#xff0c…

构建根文件系统(2)Busybox init 进程

讲init进程的启动过程从/etc/inittab出发。 内核启动init进程时已经打开/dev/console设备作为控制台&#xff0c;一般情况下Busybox init程序就使用/dev/console&#xff0c; 如果内核启动init进程的同时设置了环境变量CONSOLE或console&#xff0c;则使用环境变量所指定的设备…

C#如何在Windows中操作IIS设置FTP服务器

什么是FTPFTP(File Transfer Protocol)是TCP/IP网络上两台计算机传送文件的协议&#xff0c;使得主机间可以共享文件.可以将 Internet 信息服务 (IIS) 配置为作为 FTP 服务器来运行。 这样&#xff0c;其他计算机便可以连接到服务器并将文件复制到服务器或者从服务器复制文件。…

这是一份编程宝典,请查收!

最近&#xff0c;小编一直在整理有关编程的书籍&#xff0c;有Android、C、Java、PHP、木马、算法等类型的书籍。现在&#xff0c;小编准备将这些资料免费分享给大家&#xff01;Android应用开发入门教程&#xff08;经典版&#xff09;易学CC语言解惑HTML入门教程Java解惑&…

php备份和恢复源码,PHP数据库备份还原类

php代码<?php /*** 数据库备份还原类* author xialeistudio* date 2014-03-17* Class DatabaseTool*/class DatabaseTool{private $handler;private $config array(host > localhost,port > 3306,user > root,password > ,database > test,charset > ut…

2011年Android手机用户购买行为研究报告

http://mobile.51cto.com/hot-292153.htm转载于:https://blog.51cto.com/jueshishenhua/670081

以IP段作为监听地址

在写Socket通讯服务的时候一般需要Listen某个IP地址端口&#xff0c;但这样比较麻烦的就是部署后需要配置相关IP地址信息&#xff1b;虽然可以监听Any所有地址&#xff0c;但这种对于私有的网络服务来说并不安全。为了在发布的时候节省一些配置工作所以才想到以IP段作为监听地址…

支付宝 统一支付 php,支付宝APP支付 统一下单 php服务端 tp5

{$data input(‘post.‘);Loader::import(‘/alipay/aop/AopClient‘,EXTEND_PATH);$aop new \AopClient();$aop->appId config("alipay_app_id");$aop->rsaPrivateKey config(‘alipay_private_key‘);$aop->alipayrsaPublicKey config(‘alipay_publ…

近期资料分享汇总,还不快来看看你漏了哪份没拿?

相信&#xff0c;一直关注着我们的同学们都知道&#xff0c;小思妹分享了好多好多的资料给大家。为了方便新来的同学自取&#xff0c;小思妹又重新整理了一遍&#xff0c;直接点以下标题即可跳转&#xff01;这是我见过的最全的训练数据集&#xff0c;没有之一&#xff01;送你…

WebView 访问 url asset sd 网页

引用&#xff1a;http://www.oschina.net/code/snippet_54100_6227 [代码] [Java]代码 01//打开本包内asset目录下的index.html文件02 03wView.loadUrl(" file:///android_asset/index.html "); 04 05//打开本地sd卡内的index.html文件06 07wView.loadUrl("con…

oracle天数加个随机数,如何给一个表某列加上指定的随机数

如何给一个表某列加上指定的随机数一、原始数据create table #test (name varchar(10),ddate datetime,date1 datetime,date2 datetime)insert into #testselect 张三,2013-09-01,2013-09-01 09:00:00.000,2013-09-01 17:00:00.000 union allselect 张三,2013-09-02,2013-09-0…

MS Learn 宝藏资源库 - 学习经验分享

点击蓝字关注我们作者&#xff1a;刘轶民大家好&#xff0c;我是东北电力大学的一名在校学生&#xff0c;我叫刘轶民&#xff0c;很高兴能以 MS Learn 的受益者的身份&#xff0c;来分享一些经验与看法。作为正在上学的我来讲&#xff0c;很多时候我可能更多的去面临着新技术的…