ABP VNext + MassTransit:构建分布式事务与异步消息协作

ABP VNext + MassTransit:构建分布式事务与异步消息协作 🚀



TL;DR

  • 🚀 零侵入 MassTransit:使用 services.AddMassTransit(...) 集成,无需依赖 Volo.Abp.EventBus.MassTransit;若需 ABP 自有事件总线,可安装 Volo.Abp.EventBus.RabbitMQ
  • 💾 生产级 Saga 持久化:通过 services.AddDbContext<OrderSagaDbContext>(…) + .EntityFrameworkRepository(...) 保证状态持久化与乐观并发(需配置 RowVersion
  • 📬 标准化 Outbox:在 DbContext 内调用 builder.ConfigureEventOutbox() 并配置 AbpDistributedEventBusOptions,实现数据库写入与消息发布的原子性
  • 🔍 一体化可观测性:弃用 Prometheus 直出,采用 OpenTelemetry Trace + Metrics,通过 UseOpenTelemetryTracing()AddOpenTelemetryMetrics().AddPrometheusExporter() 深度监控消息流转

📚 1. 背景与动机

在微服务架构中,“下单 → 支付 → 发货” 属于跨服务长流程,既要求 数据一致性,又追求 高可用可观测

  • 传统 2PC 性能低、易死锁;
  • 本地事务+补偿模式缺乏集中管理与可视化;
  • Saga 模式通过状态机、持久化与补偿,提供更优的分布式事务解决方案

🛠️ 2. 环境与依赖

  • .NET:6 +

  • ABP:VNext 6.x +

  • 中间件:RabbitMQ(默认)或 Kafka

  • 核心 NuGet 包

    dotnet add package MassTransit
    dotnet add package MassTransit.RabbitMQ
    dotnet add package MassTransit.Kafka
    dotnet add package MassTransit.AspNetCore
    
  • appsettings.json

    {
      "MassTransit": {
        "UseRabbitMq": true,
        "RabbitMq": {
          "Host": "rabbitmq://localhost",
          "Username": "guest",
          "Password": "guest"
        },
        "Kafka": {
          "BootstrapServers": "localhost:9092"
        }
      }
    }
    

🔧 3. 在 ABP 模块中注册 MassTransit

3.1 强类型配置绑定

public class MassTransitOptions
{
   
   
    public bool UseRabbitMq {
   
    get; set; }
    public RabbitMqOptions RabbitMq   {
   
    get; set; } = new();
    public KafkaOptions    Kafka      {
   
    get; set; } = new();
}
services.Configure<MassTransitOptions>(Configuration.GetSection("MassTransit"));
var mtOptions = services
    .BuildServiceProvider()
    .GetRequiredService<IOptions<MassTransitOptions>>()
    .Value;

3.2 模块配置

[DependsOn(typeof(AbpAutofacModule))]
public class OrderProcessingModule : AbpModule
{
   
   
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
   
   
        var options = context.Services
            .GetConfiguration()
            .GetSection("MassTransit")
            .Get<MassTransitOptions>();

        // 先注册 Saga DbContext(用于迁移)
        context.Services.AddDbContext<OrderSagaDbContext>(builder =>
            builder.UseSqlServer(Configuration.GetConnectionString("Default")));

        context.Services.AddMassTransit(x =>
        {
   
   
            // —— Saga 持久化 & 乐观并发 —— 
            x.AddSagaStateMachine<OrderStateMachine, OrderState>()
             .EntityFrameworkRepository(r =>
             {
   
   
                 r.ExistingDbContext<OrderSagaDbContext>();
                 r.UseSqlServer();
                 r.ConcurrencyMode = ConcurrencyMode.Optimistic;
             });

            x.AddConsumer<AcceptOrderConsumer>();

            if (options.UseRabbitMq)
            {
   
   
                x.UsingRabbitMq((ctx, cfg) =>
                {
   
   
                    var rmq = options.RabbitMq;
                    cfg.Host(rmq.Host, h =>
                    {
   
   
                        h.Username(rmq.Username);
                        h.Password(rmq.Password);
                    });

                    cfg.UseMessageRetry(r => r.Interval(3, TimeSpan.FromSeconds(5)));
                    cfg.UseCircuitBreaker(cb =>
                    {
   
   
                        cb.TrackingPeriod  = TimeSpan.FromMinutes(1);
                        cb.TripThreshold   = 15;
                        cb.ActiveThreshold = 10;
                        cb.ResetInterval   = TimeSpan.FromMinutes(5);
                    });
                    cfg.UseHealthCheck(ctx);
                    cfg.UseOpenTelemetryTracing();  
                    cfg.ConfigureEndpoints(ctx);
                });
            }
            else
            {
   
   
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kookoos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值