【轉】.NET Core 事件總線,分佈式事務解決方案:CAP

【轉】.NET Core 事件總線,分佈式事務解決方案:CAPhtml

背景

相信前面幾篇關於微服務的文章也介紹了那麼多了,在構建微服務的過程當中確實須要這麼一個東西,即使不是在構建微服務,那麼在構建分佈式應用的過程當中也會遇到分佈式事務的問題,那麼 CAP 就是在這樣的背景下誕生的。git

最初打算作這個東西是在去年(2016)年末,最初是爲了解決分佈式系統中的分佈式事務的問題,而後當時有了一個大概的概念輪廓,當時我對於前面兩篇文章中關於異步消息和微服務之間通信還不是太瞭解,只是以爲這樣可以解決這一系列的問題,而後就着手作了,最後發現和這些概念居然不謀而合。github

通過大半年的不斷重構以及修改,最終 CAP 1.0 版本發佈了。做爲一個開源項目,最初項目是在個人我的Github下,而後於上個月已經貢獻給了 .NET China Foundation 組織,目前該項目由我和 DotNetCore 項目組共同維護。數據庫

CAP 介紹

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

開源協議:MIT異步

CAP 是一個在分佈式系統中(SOA,MicroService)實現事件總線及最終一致性(分佈式事務)的一個開源的 C# 庫,她具備輕量級,高性能,易使用等特色。async

你能夠輕鬆的在基於 .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 進行底層之間的消息發送,你不須要具有 RabbitMQ 或者 Kafka 的使用經驗,仍然能夠輕鬆的集成到項目中。

CAP 目前支持使用 Sql Server,MySql,PostgreSql 數據庫的項目。

CAP 同時支持使用 EntityFrameworkCore 和 Dapper 的項目,你能夠根據須要選擇不一樣的配置方式。

下面是CAP在系統中的一個不徹底示意圖:

圖中實線部分表明用戶代碼,虛線部分表明CAP內部實現。

下面,咱們看一下 CAP 怎麼集成到項目中:

Step 1:

你能夠運行下面的命令來安裝CAP NuGet 包:

PM> Install-Package DotNetCore.CAP

根據底層消息隊列,你能夠選擇引入不一樣的包:

// 若是你使用的是 Kafka
PM> Install-Package DotNetCore.CAP.Kafka

// 若是你使用的是 RabbitMQ
PM> Install-Package DotNetCore.CAP.RabbitMQ

CAP 目前支持使用 SQL Server 的項目,你須要引入:

PM> Install-Package DotNetCore.CAP.SqlServer

Step 2:

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

public void ConfigureServices(IServiceCollection services)
{
    ......
    
    services.AddDbContext<AppDbContext>();
    
    services.AddCap(x =>
    {
        // 若是你的 SqlServer 使用的 EF 進行數據操做,你須要添加以下配置:
        // 注意: 你不須要再次配置 x.UseSqlServer(""")
        x.UseEntityFramework<AppDbContext>();
        
        // 若是你使用的Dapper,你須要添加以下配置:
        x.UseSqlServer("數據庫鏈接字符串");
    
        // 若是你使用的 RabbitMQ 做爲MQ,你須要添加以下配置:
        x.UseRabbitMQ("localhost");
    
        //若是你使用的 Kafka 做爲MQ,你須要添加以下配置:
        x.UseKafka("localhost:9092");
    });
}

public void Configure(IApplicationBuilder app)
{
    .....
    
    // 添加 CAP
    app.UseCap();
}

發佈事件/消息

在 Controller 中注入 ICapPublisher 而後使用 ICapPublisher 進行消息發佈:

public class PublishController : Controller
{
    private readonly ICapPublisher _publisher;
    
    public PublishController(ICapPublisher publisher)
    {
        _publisher = publisher;
    }
    
    [Route("~/checkAccountWithTrans")]
    public async Task<IActionResult> PublishMessageWithTransaction([FromServices]AppDbContext dbContext)
    {
         using (var trans = dbContext.Database.BeginTransaction())
         {
            //指定發送的消息標題(供訂閱)和內容
            await _publisher.PublishAsync("xxx.services.account.check",
                new Person { Name = "Foo", Age = 11 });
            // 你的業務代碼。
            trans.Commit();
         }
        return Ok();
    }
}

訂閱事件/消息

Controller 中:
若是是在Controller中,直接添加[CapSubscribe("")] 來訂閱相關消息。

public class PublishController : Controller
{
    [NoAction]
    [CapSubscribe("xxx.services.account.check")]
    public async Task CheckReceivedMessage(Person person)
    {
        Console.WriteLine(person.Name);
        Console.WriteLine(person.Age);     
        return Task.CompletedTask;
    }
}

xxxService中:
若是你的方法沒有位於Controller 中,那麼你訂閱的類須要繼承 ICapSubscribe,而後添加[CapSubscribe("")]標記:

namespace xxx.Service
{
    public interface ISubscriberService
    {
        public void CheckReceivedMessage(Person person);
    }
    
    
    public class SubscriberService: ISubscriberService, ICapSubscribe
    {
        [CapSubscribe("xxx.services.account.check")]
        public void CheckReceivedMessage(Person person)
        {
            
        }
    }
}

而後在 Startup.cs 中的 ConfigureServices() 中注入你的 ISubscriberService

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

結束了,怎麼樣,是否是很簡單?

鳴謝

感謝 lan Ye 同窗對本項目的英文翻譯工做。

感謝 AlexLEWIS 同窗對本項目的其餘支持。

感謝 .NET China Foundation 團隊成員對本項目的支持。

總結

若是你有任何問題,均可以去 Github 給咱們提交 Issue,咱們會在第一時間處理。

若是你以爲這個開源項目還不錯,給個Github Star 支持一下那就太好了。

若是你以爲本篇文章對你有幫助的話,能夠關注一下博主,順手點個【推薦】哦。

GitHub stars
GitHub forks


本文地址:http://www.cnblogs.com/savorboard/p/cap.html
做者博客:Savorboard 歡迎轉載,請在明顯位置給出出處及連接

相關文章
相關標籤/搜索