分佈式事務集成netcore.Cap

最近項目中要用到分佈式事務功能,調研了DTM和Cap,最終確定用Cap來實現,Cap支持最終一致性,項目中採用MQ作爲消息中間件,數據庫用的mysql,集成步驟如下:

1、在需要發佈消息的服務中引入如下的包,我是放在了api層

    <PackageReference Include="DotNetCore.CAP" Version="5.2.0" />
    <PackageReference Include="DotNetCore.CAP.Dashboard" Version="5.2.0" />
    <PackageReference Include="DotNetCore.CAP.MySql" Version="5.2.0" />
    <PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="5.2.0" />

2、編寫Cap擴展服務

public static class CapExtensions
    {
        public static void AddMyCap(this IServiceCollection services, IConfiguration configuration)
        {

            services.AddCap(
                a => {
                    a.UseEntityFramework<QualificationDbContext>();
                    a.UseMySql(configuration.GetConnectionString("Default"));
                    //僅用於測試,正式使用後要換成可配置項
                    a.UseRabbitMQ(rb =>
                    {
                        rb.HostName = "118.111.111.111";
                        rb.UserName = "root";
                        rb.Password = "123456";
                        rb.Port = 5672;
                        rb.VirtualHost = "/";
                       
                    });

                    // 添加cap後臺監控頁面(人工處理);頁面地址爲“/cap”;如:http://www.site.com/cap
                    a.UseDashboard();
                    // 配置定時器重試策略
                    a.FailedRetryInterval = 10; //重試間隔時間(秒),使用默認的就可以,可不用配置
                    a.FailedRetryCount = 5; //重試次數

                }
                );
            services.AddDbContext<QualificationDbContext>();
        }
    }

3、在配置文件中增加服務

 context.Services.AddMyCap(configuration);

4、在控制器中註冊ICapPublisher類就可以發佈消息了

namespace Qualification.Controllers
{
    [Route("api/Test")]

    public class TestController : AbpController
    {
        private readonly ICapPublisher capPublisher;
        public TestController(ICapPublisher _capPublisher)
        {
            this.capPublisher = _capPublisher;
        }
        /// <summary>
        /// 測試cap功能:創建證照時發佈消息,在服務平臺進行訂閱
        /// </summary>
        /// <returns></returns>
        [HttpPost("CreateQualification")]
        public async Task<IActionResult> CreateQualification()
        {
            try
            {
                this.capPublisher.Publish<CreateQualificationCapDto>("Qualification.Create.Success", new CreateQualificationCapDto { Name = "Qualification", Count = 10 });
                return Ok("創建產品證照成功");
            }
            catch (Exception ex)
            {

                throw;
            }

        }
    }

    public class CreateQualificationCapDto
        {
           public string Name { get; set; }
           public int Count { get; set; }
        }
}

3、在訂閱的程序b中同樣引用cap的依賴包

 

 4、同樣寫Cap服務的擴展程序,和服務a是一樣的,這裏就不再重複了

5、在訂閱服務類中繼承ICapSubscribe,因爲我是用的ABP框架,所以繼承了ITransientDependency接口,爲了是注入服務實體,如果你不是用這個框架,請在手動注入服務:services.AddSingleton<Controllers.CapSubscribeService>();否則,訂閱不到數據。

public interface ICapSubscribeService
    {
        public void UpdateOrder(CreateQualificationCapDto createQualification);
    }

    public class CapSubscribeService : ICapSubscribeService, ICapSubscribe, ITransientDependency
    {
        [CapSubscribe("Qualification.Create.Success")]
        public void UpdateOrder(CreateQualificationCapDto createQualification)
        {
            var data = createQualification;
        }
    }

    public class CreateQualificationCapDto
    {
        public string Name { get; set; }
        public int Count { get; set; }
    }

6、同時啓動兩個系統數據庫中會自動生成兩個表

 

 7、服務a中發佈一個消息後在服務b中會自動訂閱到

 

 8、系統爲我們默認生成了交換機和隊列,並且可以查看到發了信息

 

 

 

9、後續還會加上發佈消息時與業務代碼處理放在一個事務中,發佈與訂閱錯誤時回調方法。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章