我们可以通过 masstransit 一起使用 RabbitMQ 和 Mediatr 吗?

Posted

技术标签:

【中文标题】我们可以通过 masstransit 一起使用 RabbitMQ 和 Mediatr 吗?【英文标题】:Can we use RabbitMQ and Mediatr together using masstransit? 【发布时间】:2020-09-16 22:04:29 【问题描述】:

我创建了一个微服务应用程序,该应用程序使用 MassTransitRabbitMQ 进行微服务通信。 每个微服务都使用干净的架构开发,因此我们在每个微服务中都有 MediatR。 是否也可以使用 MassTransit 进行内部通信?所以我可以对所有服务使用相同的签名,当我想公开一个服务以在微服务间使用时,它会很容易做到。 所以 MediatR 用于内部通信,RabbitMQ 用于内部通信,整个宇宙都在 MassTransit 系统上。[更新]我的问题是我们如何配置消费者,以便一些可以用于内部通信(通过 MediatR),有些可用于外部通信(通过 RabbitMQ),并且可以轻松地将它们从内部更改为外部。[Update2] 例如,这是我的 MassTransit 注册:

services.AddMassTransit(x =>
        
            x.AddConsumers(Assembly.GetExecutingAssembly());

            x.AddBus(provider =>
                Bus.Factory.CreateUsingRabbitMq(cfg =>
                
                    cfg.Host(new Uri(config.RabbitMQ.Address), h =>
                    
                        h.Username(config.RabbitMQ.Username);
                        h.Password(config.RabbitMQ.Password);
                    );

                    cfg.ReceiveEndpoint("my-queue", ep =>  ep.ConfigureConsumers(provider); );
                ));


            x.AddMediator((provider, cfg) =>  cfg.ConfigureConsumers(provider); );
        );

内部沟通和外部沟通有什么不同?换句话说,我怎样才能将一些消费者注册到 MediatR 而一些消费者注册到 RabbitMQ?

【问题讨论】:

根据您的更新,您需要使用 MassTransit 中介为消费者提供一个单一界面,您可以将其移动到中介或 RabbitMQ 端点。 【参考方案1】:

它们可以一起使用,MassTransit 也有自己的 Mediator 实现,因此您可以编写一次处理程序,然后通过 Mediator 或通过 RabbitMQ 等持久传输来使用它们。

有可用的videos 可以带您了解这些功能,从调解器开始,然后迁移到 RabbitMQ。

【讨论】:

感谢您的评论。其实我知道两者都可以使用。我想知道我们如何配置一些用于内部通信(通过 MediatR)和一些用于外部通信(通过 RabbitMQ)的消费者 我们可以在公共交通中使用主 mediatR 库吗? @克里斯 确定吗?我没有使用过 MediatR,所以我不知道它是如何工作的,但我想这两者可以在同一个项目中使用。然而,它们并没有集成以协同工作。【参考方案2】:

我发现我应该为每个创建一个单独的总线。然后外部服务继承自 IExternalConsumer 之类的接口,因此我可以将它们与内部服务分开并将它们添加到相关总线: 第 7 版更新

        // find consumers
        var types = AssemblyTypeCache.FindTypes(new[]Assembly.GetExecutingAssembly(),TypeMetadataCache.IsConsumerOrDefinition).GetAwaiter().GetResult();
        var consumers = types.FindTypes(TypeClassification.Concrete | TypeClassification.Closed).ToArray();
        var internals = new List<Type>();
        var externals = new List<Type>();
        foreach (Type type in consumers)
        
            if (type.HasInterface<IExternalConsumer>())
                externals.Add(type);
            else
                internals.Add(type);
        

        services.AddMediator(x =>
        
            x.AddConsumers(internals.ToArray());
            x.ConfigureMediator((provider, cfg) => cfg.UseFluentValidation());
        );
        services.AddMassTransit<IExternalBus>(x =>
        
            x.AddConsumers(externals.ToArray());
            x.AddBus(provider =>
                Bus.Factory.CreateUsingRabbitMq(cfg =>
                
                    cfg.Host(new Uri(config.RabbitMQ.Address), h =>
                    
                        h.Username(config.RabbitMQ.Username);
                        h.Password(config.RabbitMQ.Password);
                    );

                    cfg.ReceiveEndpoint(apiProviderName, ep =>  ep.ConfigureConsumers(provider); );

                ));
        );

        services.AddMassTransitHostedService();

【讨论】:

只是为了更新,在 v7 中,.AddMediator() 和 .AddMassTransit() 可以在同一个容器中配置,而无需使用单独的总线。 我一直在尝试使用 MassTransit.AspNetCore 7.0.3,但无法使用 .AddMediator()。 services.AddMassTransit(cfg => cfg.AddConsumer(); cfg.AddMediator(); // 通过这种方法,我应该在我的控制器或 MediatR 控制器中使用 MassTransit 接口吗?您可以分享任何示例解决方案吗?

以上是关于我们可以通过 masstransit 一起使用 RabbitMQ 和 Mediatr 吗?的主要内容,如果未能解决你的问题,请参考以下文章

MassTransit 确保在发布消息之前创建队列

RabbitMQ 和 MassTransit 之间的连接

在与 Entity Framework 的事务中通过 MassTransit 发送消息

是否可以使用 MassTransit 为 RabbitMQ 队列注册多个消费者?

使用 BizTalk 而不是 NServiceBus 或 MassTransit 的优点/缺点

未登录 MassTransit Mediator 的异常