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

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: .NET Core 事件总线,分布式事务解决方案:CAP

数据库代码


CREATE DATABASE OrderTest;
GO
USE OrderTest;
GO
CREATE TABLE Product(
  Id INT PRIMARY KEY IDENTITY,
  ProductName VARCHAR(30) NOT NULL,
  Price INT NOT NULL,
  Stock INT NOT NULL
);
CREATE TABLE [Order]
(
  Id INT PRIMARY KEY IDENTITY,
  ProductId INT NOT NULL,
  UserName VARCHAR(30) NOT NULL,
  Quantity INT NOT NULL
);
GO
INSERT INTO dbo.Product
(
    ProductName,
    Price,
    Stock
)
VALUES ('衣服',30,30 ),('鞋子',20,20 ),('帽子',10,10 ),('外套',25,30 )


官网:https://cap.dotnetcore.xyz/user-guide/zh/getting-started/quick-start/


背景


在构建分布式应用的过程中也会遇到分布式事务的问题,那么 CAP 就是在这样的背景下诞生的。


https://github.com/dotnetcore


CAP 介绍


Github:https://github.com/dotnetcore/CAP


开源协议:MIT


CAP 是一个在分布式系统中(SOA,MicroService)实现事件总线及最终一致性(分布式事务)的一个开源的 C# 库,她具有轻量级,高性能,易使用等特点。


你可以轻松的在基于 .NET Core 技术的分布式系统中引入CAP,包括但限于 ASP.NET Core 和 ASP.NET Core on .NET Framework。


CAP 以 NuGet 包的形式提供,对项目无任何入侵,你仍然可以以你喜爱的方式来构建分布式系统。


CAP 具有 Event Bus 的所有功能,并且CAP提供了更加简化的方式来处理EventBus中的发布/订阅。


CAP 具有消息持久化的功能,也就是当你的服务进行重启或者宕机时,她可以保证消息的可靠性。


CAP 实现了分布式事务中的最终一致性,你不用再去处理这些琐碎的细节。


CAP 提供了基于 Microsoft DI 的 API 服务,她可以和你的 ASP.NET Core 系统进行无缝结合,并且能够和你的业务代码集成支持强一致性的事务处理。


CAP 是开源免费的。CAP基于MIT协议开源,你可以免费的在你的私人或者商业项目中使用,不会有人向你收取任何费用。


Getting Started


目前, CAP 同时支持使用 RabbitMQ,Kafka,Azure Service Bus 等进行底层之间的消息发送,你不需要具备这些消息队列的使用经验,仍然可以轻松的集成到项目中。


CAP 目前支持使用 Sql Server,MySql,PostgreSql,MongoDB 数据库的项目。


CAP 同时支持使用 EntityFrameworkCore 和 ADO.NET 的项目,你可以根据需要选择不同的配置方式。


下面是CAP在系统中的一个不完全示意图:

1673442616030.jpg

图中实线部分代表用户代码,虚线部分代表CAP内部实现。


下面,我们看一下 CAP 怎么集成到项目中:


Step 1:

你可以运行下面的命令来安装CAP NuGet 包:

PM> Install-Package DotNetCore.CAP


根据底层消息队列,你可以选择引入不同的包:

PM> Install-Package DotNetCore.CAP.Kafka
PM> Install-Package DotNetCore.CAP.RabbitMQ
PM> Install-Package DotNetCore.CAP.AzureServiceBus


CAP 目前支持使用 SQL Server, PostgreSql, MySql, 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     //需要 MongoDB 4.0+ 集群


Step 2:

在 Startup.cs 文件中,添加如下配置:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    var sqlConnection = Configuration.GetConnectionString("OrderTestConnection");
    services.AddDbContext<OrderDbContext>(p=>p.UseSqlServer(sqlConnection));
    RabbitMQOptions rabbitOptions = new RabbitMQOptions();
    Configuration.GetSection("RabbitMQ").Bind(rabbitOptions);
    services.AddCap(p =>
                    {
                        p.UseEntityFramework<OrderDbContext>();
                        p.UseRabbitMQ(mq =>
                                      {
                                          mq.HostName = rabbitOptions.HostName;
                                          mq.VirtualHost = rabbitOptions.VirtualHost;
                                          mq.UserName = rabbitOptions.UserName;
                                          mq.Password = rabbitOptions.Password;
                                          mq.Port = rabbitOptions.Port;
                                      });
                        p.UseSqlServer(sqlConnection);
                    });
}


Step 3:

appsetting.json 文件配置:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
    "AllowedHosts": "*",
    "ConnectionStrings": {
        "OrderTestConnection": "server=.;uid=sa;pwd=123456;database=ordertest;"
    },
    "RabbitMQ": {
        "HostName": "172.16.20.157",
        "VirtualHost": "/",
        "UserName": "admin",
        "Password": "admin",
        "Port": "5672"
    } 
}


发布事件/消息


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

public class PublishController : Controller
{
    private readonly ICapPublisher _capBus;
    private readonly OrderDbContext _context;
    public OrderController(ICapPublisher capBus, OrderDbContext context)
    {
        _capBus = capBus;
        _context = context;
    }
    public IActionResult CreateOrder()
    {
        return View();
    }
    [HttpPost]
    public IActionResult Submit(Order order)
    {
        using var tran = _context.Database.BeginTransaction(_capBus);
        try
        {
            _context.Order.Add(order);
            _context.SaveChanges();
            //发送消息
            _capBus.Publish("order.create",order);
            tran.Commit();
            return Redirect("/home/index");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            tran.Rollback();
            return BadRequest(e.Message);
        }
    }
}


订阅事件/消息


在 Controller 中:

如果是在Controller中,直接添加[CapSubscribe("")] 来订阅相关消息。

public class ConsumerController : Controller
{
    private readonly OrderDbContext _context;
    public ConsumerController( OrderDbContext context)
    {
        _context = context;
    }
    [CapSubscribe(name:"order.create")] //这个要与publisher 方法中的name要一致
    public void OrderCreateConsumer(Order order)
    {
        //减库存
        var product = _context.Product.FirstOrDefault(p=>p.Id==order.ProductId);
        product.Stock -= order.Quantity;
        _context.SaveChanges();
    }
}


在 xxxService中:

如果你的方法没有位于Controller 中,那么你订阅的类需要继承 ICapSubscribe,然后添加[CapSubscribe("")]标记:

namespace xxx.Service
{
    public interface ISubscriberService
    {
      public void CheckReceivedMessage(DateTime time);
    }
    public class SubscriberService: ISubscriberService, ICapSubscribe
    {
      [CapSubscribe("xxxx.services.show.time")]
      public void CheckReceivedMessage(DateTime time)
      {
      }
    }
}


然后在 Startup.cs 中的 ConfigureServices() 中注入你的 ISubscriberService 类

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<ISubscriberService,SubscriberService>();
}


结束了,怎么样,是不是很简单?


异常解决


RabbitMQ : SubscriberNotFoundException #63

es() 中注入你的 ISubscriberService 类

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<ISubscriberService,SubscriberService>();
}


结束了,怎么样,是不是很简单?

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
1月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
109 3
|
2月前
|
存储 SQL 微服务
常用的分布式事务解决方案(三)
常用的分布式事务解决方案(三)
|
1月前
|
存储 开发框架 JSON
ASP.NET Core OData 9 正式发布
【10月更文挑战第8天】Microsoft 在 2024 年 8 月 30 日宣布推出 ASP.NET Core OData 9,此版本与 .NET 8 的 OData 库保持一致,改进了数据编码以符合 OData 规范,并放弃了对旧版 .NET Framework 的支持,仅支持 .NET 8 及更高版本。新版本引入了更快的 JSON 编写器 `System.Text.UTF8JsonWriter`,优化了内存使用和序列化速度。
|
1月前
|
监控 网络安全 调度
Quartz.Net整合NetCore3.1,部署到IIS服务器上后台定时Job不被调度的解决方案
解决Quartz.NET在.NET Core 3.1应用中部署到IIS服务器上不被调度的问题,通常需要综合考虑应用配置、IIS设置、日志分析等多个方面。采用上述策略,结合细致的测试和监控,可以有效地提高定时任务的稳定性和可靠性。在实施任何更改后,务必进行充分的测试,以验证问题是否得到解决,并监控生产环境的表现,确保长期稳定性。
58 1
|
2月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
2月前
|
开发框架 .NET 中间件
ASP.NET Core Web 开发浅谈
本文介绍ASP.NET Core,一个轻量级、开源的跨平台框架,专为构建高性能Web应用设计。通过简单步骤,你将学会创建首个Web应用。文章还深入探讨了路由配置、依赖注入及安全性配置等常见问题,并提供了实用示例代码以助于理解与避免错误,帮助开发者更好地掌握ASP.NET Core的核心概念。
99 3
|
2月前
|
存储 安全 物联网
.NET 跨平台工业物联网网关解决方案
【9月更文挑战第28天】本文介绍了利用 .NET 构建跨平台工业物联网网关的解决方案。通过 .NET Core 和多种通信协议(如 MQTT 和 Modbus),实现工业设备的高效接入和数据采集。系统架构包括设备接入层、数据处理层、通信层、应用层和数据库层,确保数据的准确采集、实时处理和安全传输。此外,还详细阐述了设备身份认证、数据加密及安全审计等机制,确保系统的安全性。该方案适用于不同操作系统和工业环境,具备高度灵活性和扩展性。
|
2月前
|
消息中间件 中间件 关系型数据库
常用的分布式事务解决方案(四)
常用的分布式事务解决方案(四)
|
1月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
1月前
|
JavaScript 调度
Vue事件总线(EventBus)使用指南:详细解析与实战应用
Vue事件总线(EventBus)使用指南:详细解析与实战应用
63 1
下一篇
无影云桌面