秒杀-Masstransit配置

appsetting.json

复制代码
/ RabbitMq
  "RabbitMq": {
    "HostName": "127.0.0.1",
    "VirtualHost": "/",
    "UserName": "pony",
    "Password": "123456",
    "Port": "15672"
  },

Program.cs

复制代码
//注册MassTransit
var rabbitmqInfo = AppSettings.Get<RabbitMqConfig>("RabbitMq");
builder.Services.AddConsumerListener();

Program.cs 中的 builder.Services.AddConsumerListener() 是 MassTransit 消息队列框架的核心配置,负责将消费者(CreateOrderConsumer、StockConfirmQueue)与 RabbitMQ 绑定,实现消息的接收和处理。

AddConsumerListener 方法的作用是将自定义的消费者与 RabbitMQ 的交换机、队列、路由规则绑定,让消费者能自动接收并处理指定的消息。Program.cs 调用 AddConsumerListener() → 触发 配置 → 框架自动创建 RabbitMQ 连接、交换机、队列,并将消费者与队列绑定 → 消费者可监听并处理队列中的消息。将配置逻辑封装为扩展方法,新增消费者时只需添加一个新方法,符合开闭原则,便于维护。具体作用已在代码注释中。

cs 复制代码
using MassTransit;
using MassTransit.RabbitMqTransport;

/// <summary>
/// MassTransit 消费者配置扩展类
/// 用于统一注册消息消费者并配置 RabbitMQ 连接、队列、交换机等信息
/// </summary>
public static class ConsumerListenerExtensions
{
    /// <summary>
    /// 向服务容器添加 MassTransit 消费者配置
    /// 封装了消息队列的核心配置逻辑,简化 Program.cs 中的代码
    /// </summary>
    /// <param name="service">服务集合</param>
    /// <returns>配置后的服务集合</returns>
    public static IServiceCollection AddConsumerListener(this IServiceCollection service)
    {
        // 注册 MassTransit 框架及相关配置
        service.AddMassTransit(cfg =>
        {
            // 添加延迟消息调度器(支持发送定时/延迟消息)
            cfg.AddDelayedMessageScheduler();

            // 注册自定义消费者:库存确认消费者(处理订单创建确认消息)
            cfg.AddConsumer<StockConfirmQueue>();
            // 注册自定义消费者:创建订单消费者(处理库存扣减后的订单创建消息)
            cfg.AddConsumer<CreateOrderConsumer>();

            // 配置 RabbitMQ 作为消息传输层
            cfg.UsingRabbitMq((ctx, rb) =>
            {
                // 配置 RabbitMQ 服务器连接信息
                rb.Host("localhost", h =>
                {
                    h.Username("pony");   // RabbitMQ 用户名
                    h.Password("123456"); // RabbitMQ 密码
                });

                // 启用延迟消息调度器(与上面的 AddDelayedMessageScheduler 对应)
                rb.UseDelayedMessageScheduler();

                // 配置库存确认队列与消费者的绑定关系
                StockConfirmQueueDirect(rb, ctx);
                // 配置创建订单队列与消费者的绑定关系
                CreateOrderQueueDirect(rb, ctx);
            });
        });

        return service;
    }

    /// <summary>
    /// 配置 "库存确认队列" 的详细信息(队列、交换机、路由规则)
    /// 用于处理订单服务发送的 "订单创建确认" 消息
    /// </summary>
    /// <param name="cfg">RabbitMQ 总线配置器</param>
    /// <param name="ctx">总线注册上下文(用于依赖注入)</param>
    private static void StockConfirmQueueDirect(IRabbitMqBusFactoryConfigurator cfg, IBusRegistrationContext ctx)
    {
        // 创建/配置接收队列:队列名称为 "stockConfirmQueue"
        cfg.ReceiveEndpoint("stockConfirmQueue", e =>
        {
            // 禁用自动创建交换机(手动控制交换机配置,避免框架自动生成不符合预期的结构)
            e.ConfigureConsumeTopology = false;

            // 将队列与 "StockConfirmQueue" 消费者绑定:该队列的消息由该消费者处理
            e.Consumer<StockConfirmQueue>(ctx);

            // 队列持久化:RabbitMQ 重启后队列不丢失(保证消息不丢失)
            e.Durable = true;
            // 不自动删除队列:即使没有消费者连接,队列也不会被删除
            e.AutoDelete = false;

            // 消息消费失败时的重试策略:重试 3 次,每次间隔 3000 毫秒(3秒)
            // 解决网络抖动、服务临时不可用等问题导致的消费失败
            e.UseMessageRetry(r => r.Interval(3, 3000));

            // 预取计数:每次从队列拉取 10 条消息给消费者处理
            // 控制消息处理速度,避免单消费者过载(秒杀场景需合理限流)
            e.PrefetchCount = 10;

            // 将队列绑定到交换机 "stockConfirmQueue.direct"
            e.Bind("stockConfirmQueue.direct", b =>
            {
                b.ExchangeType = "direct";       // 交换机类型:direct(精确路由)
                b.RoutingKey = "orderpublic";    // 路由键:只有匹配该键的消息才会进入队列
            });
        });
    }

    /// <summary>
    /// 配置 "创建订单队列" 的详细信息(队列、交换机、路由规则)
    /// 用于处理库存服务发送的 "库存扣减成功" 消息,触发订单创建
    /// </summary>
    /// <param name="cfg">RabbitMQ 总线配置器</param>
    /// <param name="ctx">总线注册上下文(用于依赖注入)</param>
    private static void CreateOrderQueueDirect(IRabbitMqBusFactoryConfigurator cfg, IBusRegistrationContext ctx)
    {
        // 创建/配置接收队列:队列名称为 "createOrderConsumer"
        cfg.ReceiveEndpoint("createOrderConsumer", e =>
        {
            e.ConfigureConsumeTopology = false; // 禁用自动创建交换机,手动控制

            // 将队列与 "CreateOrderConsumer" 消费者绑定:该队列的消息由该消费者处理
            e.Consumer<CreateOrderConsumer>(ctx);

            // 队列持久化 + 不自动删除(保证高可用,消息不丢失)
            e.Durable = true;
            e.AutoDelete = false;

            // 消息重试策略:3次重试,间隔3秒(同库存确认队列,保证消息最终被处理)
            e.UseMessageRetry(r => r.Interval(3, 3000));

            // 预取计数10(控制秒杀场景下的消息处理速度)
            e.PrefetchCount = 10;

            // 将队列绑定到交换机 "createOrderConsumer.direct"
            e.Bind("createOrderConsumer.direct", b =>
            {
                b.ExchangeType = "direct";       // 交换机类型:direct(精确路由)
                b.RoutingKey = "orderpublic";    // 路由键:匹配该键的消息进入队列
            });
        });
    }
}
相关推荐
e***716713 小时前
【RabbitMQ】超详细Windows系统下RabbitMQ的安装配置
windows·分布式·rabbitmq
k***216013 小时前
使用 Docker 部署 RabbitMQ 的详细指南
docker·容器·rabbitmq
B***y88513 小时前
Spring Boot 中 RabbitMQ 的使用
spring boot·rabbitmq·java-rabbitmq
唐青枫13 小时前
C# 原始字符串字面量全面解析:多行字符串终于优雅了!
c#·.net
缺点内向15 小时前
如何在 C# 中将 Excel 工作表拆分为多个窗格
开发语言·c#·.net·excel
夏霞1 天前
c# 使用vs code 创建.net8.0以及.net6.0 webApi项目的教程
开发语言·c#·.net
追逐时光者1 天前
C#/.NET/.NET Core优秀项目和框架2025年11月简报
后端·.net
Aevget1 天前
界面控件DevExpress WinForms中文教程:Data Grid - 如何获取汇总值?
ui·.net·界面控件·winform·devexpress
2501_941403761 天前
智能城市公共安全平台中的多语言语法引擎与实时预警实践
rabbitmq
时光追逐者1 天前
C# 中 ?、??、??=、?: 、?. 、?[] 各种问号的用法和说明
开发语言·c#·.net·.net core