.NET開源的處理分散式事務的解決方案

追逐時光者發表於2023-11-30

前言

在分散式系統中,由於各個系統服務之間的獨立性和網路通訊的不確定性,要確保跨系統的事務操作的最終一致性是一項重大的挑戰。今天給大家推薦一個.NET開源的處理分散式事務的解決方案基於 .NET Standard 的 C# 庫:CAP。

CAP專案介紹

CAP 是一個基於 .NET Standard 的 C# 庫,它是一種處理分散式事務的解決方案,同樣具有 EventBus 的功能,它具有輕量級、易使用、高效能等特點。CAP 是一個EventBus,同時也是一個在微服務或者SOA系統中解決分散式事務問題的一個框架。它有助於建立可擴充套件,可靠並且易於更改的微服務系統。

什麼是 EventBus?

事件匯流排是一種機制,它允許不同的元件彼此通訊而不彼此瞭解。元件可以將事件傳送到Eventbus,而無需知道是誰來接聽或有多少其他人來接聽。元件也可以偵聽Eventbus上的事件,而無需知道誰傳送了事件。這樣,元件可以相互通訊而無需相互依賴。同樣,很容易替換一個元件。只要新元件瞭解正在傳送和接收的事件,其他元件就永遠不會知道。

CAP架構預覽

CAP支援的儲存

SQL Server、MySQL、PostgreSql、MongoDB、In-Memory Storage。

CAP 支援以下幾種運輸方式

RabbitMQ、Kafka、Azure Service Bus、Amazon SQS、NATS、In-Memory Queue、Redis Streams、Apache Pulsar。

怎麼選擇運輸器

專案原始碼

快速開始

安裝DotNetCore.CAP Nuget包

CAP 支援主流的訊息佇列作為傳輸器:

我本地安裝的是DotNetCore.CAP.RabbitMQ。

//你可以按需選擇下面的包進行安裝:
PM> Install-Package DotNetCore.CAP.Kafka
PM> Install-Package DotNetCore.CAP.RabbitMQ
PM> Install-Package DotNetCore.CAP.AzureServiceBus
PM> Install-Package DotNetCore.CAP.AmazonSQS
PM> Install-Package DotNetCore.CAP.NATS
PM> Install-Package DotNetCore.CAP.RedisStreams
PM> Install-Package DotNetCore.CAP.Pulsar

CAP 提供了主流資料庫作為儲存:

我本地安裝的是DotNetCore.CAP.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

配置CAP到 Program.cs 檔案中,如下:

            builder.Services.AddCap(x =>
            {
                //如果你使用的 EF 進行資料操作,你需要新增如下配置:
                //配置資料庫上下文
                x.UseEntityFramework<AppDbContext>();

                //如果你使用的 MongoDB,你可以新增如下配置:
                x.UseMongoDB("ConnectionStrings");  //注意,僅支援MongoDB 4.0+叢集

                //CAP RabbitMQ 配置
                x.UseRabbitMQ(rab => {
                    rab.HostName = "192.0.1.1";
                    rab.Password = "123456";
                    rab.Port = 5672;
                    rab.UserName = "123456";
                });
            });

釋出

在 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);

        // Publish delay message
        _capBus.PublishDelayAsync(TimeSpan.FromSeconds(delaySeconds), "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)
        {
        }
    }
}

專案原始碼地址

更多專案實用功能和特性歡迎前往專案開源地址檢視?,別忘了給專案一個Star支援?。

GitHub開源地址:https://github.com/dotnetcore/CAP

官方文件:https://cap.dotnetcore.xyz/

優秀專案和框架精選

該專案已收錄到C#/.NET/.NET Core優秀專案和框架精選中,關注優秀專案和框架精選能讓你及時瞭解C#、.NET和.NET Core領域的最新動態和最佳實踐,提高開發工作效率和質量。坑已挖,歡迎大家踴躍提交PR推薦或自薦(讓優秀的專案和框架不被埋沒?)。

https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

DotNetGuide技術社群交流群

  • DotNetGuide技術社群是一個面向.NET開發者的開源技術社群,旨在為開發者們提供全面的C#/.NET/.NET Core相關學習資料、技術分享和諮詢、專案推薦、招聘資訊和解決問題的平臺。
  • 在這個社群中,開發者們可以分享自己的技術文章、專案經驗、遇到的疑難技術問題以及解決方案,並且還有機會結識志同道合的開發者。
  • 我們致力於構建一個積極向上、和諧友善的.NET技術交流平臺,為廣大.NET開發者帶來更多的價值和成長機會。

歡迎加入DotNetGuide技術社群微信交流群?