秒杀-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";    // 路由键:匹配该键的消息进入队列
            });
        });
    }
}
相关推荐
波波00710 分钟前
Native AOT 能改变什么?.NET 预编译技术深度剖析
开发语言·.net
Crazy Struggle20 小时前
.NET 中如何快速实现 List 集合去重?
c#·.net
极客智造1 天前
ImageSharp 实战应用指南:.NET 跨平台图像处理落地实践
图像处理·.net
时光追逐者1 天前
一个基于 .NET + Vue 实现的通用权限管理平台(RBAC模式),前后端分离模式,开箱即用!
前端·vue.js·c#·.net·.net core
大黄说说1 天前
在 .NET Aspire 项目中集成 AgileConfig 实现统一配置管理
.net
坊钰1 天前
【Rabbit MQ】Rabbit MQ 的结构详解,传输机制!!!
java·rabbitmq
wy3136228211 天前
C#——报错:System.Net.Sockets.SocketException (10049): 在其上下文中,该请求的地址无效。
开发语言·c#·.net
缺点内向2 天前
C#编程实战:如何为Word文档添加背景色或背景图片
开发语言·c#·自动化·word·.net
请叫我头头哥2 天前
SpringBoot进阶教程(八十九)rabbitmq长链接及域名TTL,多机房切换配置重连能力
rabbitmq·springboot
三水不滴2 天前
对比一下RabbitMQ和RocketMQ
经验分享·笔记·分布式·rabbitmq·rocketmq