C# 使用exchange和使用MassTransit的路由密钥发布邮件

C# 使用exchange和使用MassTransit的路由密钥发布邮件,c#,message-queue,masstransit,rabbitmq-exchange,C#,Message Queue,Masstransit,Rabbitmq Exchange,我已经关注MassTransit好几个星期了,我很好奇它的可能性。然而,我似乎不能完全正确地理解这些概念 预期行为 我想用路由密钥将消息发布到“direct”exchange,该密钥绑定到两个不同的队列以执行其他活动 当我尝试使用MassTransit实现更好的可伸缩性时。我发现MassTransit基于具有扇出类型的队列名称创建自己的交换 通过exchange和路由密钥发布邮件的经典代码 using (var connection = factory.CreateConnection())

我已经关注MassTransit好几个星期了,我很好奇它的可能性。然而,我似乎不能完全正确地理解这些概念

预期行为 我想用路由密钥将消息发布到“direct”exchange,该密钥绑定到两个不同的队列以执行其他活动

当我尝试使用MassTransit实现更好的可伸缩性时。我发现MassTransit基于具有扇出类型的队列名称创建自己的交换

通过exchange和路由密钥发布邮件的经典代码

using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                channel.ExchangeDeclare(exchange, "direct");

                var body = Encoding.UTF8.GetBytes(message);

                channel.BasicPublish(exchange, routingKey, null, body);
                Console.WriteLine(" [x] Sent {0}", message);
            }
        }

是否有办法在MassTransit中使用routingkey配置直接或主题交换?

这是MassTransit不支持的方案。MassTransit将始终创建扇出队列。如果您自己管理拓扑,则可以使用
IEndpoint.Send
将消息直接发送到您创建的exchange。在这种情况下,您放弃了MT提供的很多功能

我也不确定在这种情况下“更好的可伸缩性”意味着什么。扇出交换比直接交换性能更好(在大多数情况下),因为不需要处理路由逻辑


如果您在上澄清您的性能问题,我们可能会在这方面为您提供更多帮助。

MassTransit在不使用主题交换的情况下处理发布和订阅,而是为正在发布的消息类型创建交换,并将这些交换绑定到消费者队列

RabbitMQ的路由密钥方法效率较低,它更喜欢使用exchange结构以简化消息路由(无需维护哈希表)


与处理交换和路由密钥不同,只需定义您的命令和/或事件类型,然后发送或发布这些消息,并让使用者完成他们的工作。

以下代码执行相同的工作,但需要一个额外的扇出交换:

TestMessage(直接交换)->TestMessage_队列(扇出交换)->TestMessage_队列(队列)

var bus=bus.Factory.CreateUsingRabbitMq(cfg=>
{
var host=cfg.host(新Uri(“rabbitmq://localhost,h=>
{
h、 用户名(“客人”);
h、 密码(“客人”);
});
Send(x=>{x.UseRoutingKeyFormatter(context=>“routingKey”);});
Message(x=>x.SetEntityName(“TestMessage”);
Publish(x=>{x.ExchangeType=ExchangeType.Direct;});
ReceiveEndpoint(主机,“TestMessage_队列”,e=>
{
e、 bindMessageExchange=false;
e、 消费者();
e、 绑定(“TestMessage”,x=>
{
x、 ExchangeType=ExchangeType.Direct;
x、 RoutingKey=“RoutingKey”;
});
});
});
bus.Start();

感谢您的评论,我的流程需要多个发布者并行发布消息,因此考虑了“直接”或“主题”交换,但MassTransit不支持这些交换。您是否对处理此问题的最佳方法有任何建议,或者您更喜欢使用多个队列进行此过程。另外,如果你能告诉我MassTransit的架构,我也会很有帮助。我真的不知道你想做什么。并行发布消息对我来说没什么意义。使用MT 3.0,您可以进行异步发布。不过,一切或多或少都与消息传递并行。如果一个线程正在发布,那么另一个线程也可以发布。消费也是一样。基本上,忘记RMQ中的拓扑结构,只需定义带有类型(最好是接口)的消息契约,让MT为您将其绑定在一起。创建额外的类型虽然非常干净,但可能会很乏味。一种诱人的方法是,您的总线甚至不知道交换的确切类型是什么,因为您将所有内容都封装在一个通用的“类包装器”类型中(可能会丢失静态类型,因为只有一个包装器类型)。然而,单一包装器类型的一个显著优点是,从技术上讲,从单个交换机到所有订阅者都有一个风扇,因此所有订阅者都检索所有消息,过滤必须在处理程序内部完成。这就是路由密钥方法变得方便的地方。通过将每个包装的消息和路由密钥映射到队列,使用显式密钥,您可以精确地控制订阅。幸运的是,正如@jan mucinsky在另一个答案中提到的,这似乎在MT中有效。我不是在提倡这种模式,我只是说这在技术上是可行的,而且背后有一个理论基础。哪个版本是这样的?verion 5.5.1没有发送或发布功能
var bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
    var host = cfg.Host(new Uri("rabbitmq://localhost"), h =>
    {
        h.Username("guest");
        h.Password("guest");
    });
    cfg.Send<TestMessage>(x => { x.UseRoutingKeyFormatter(context => "routingKey"); });
    cfg.Message<TestMessage>(x => x.SetEntityName("TestMessage"));
    cfg.Publish<TestMessage>(x => { x.ExchangeType = ExchangeType.Direct; });
    cfg.ReceiveEndpoint(host, "TestMessage_Queue", e =>
    {
        e.BindMessageExchanges = false;
        e.Consumer<UpdateCustomerConsumer>();
        e.Bind("TestMessage", x =>
        {
            x.ExchangeType = ExchangeType.Direct;
            x.RoutingKey = "routingKey";
        });
    });
});

bus.Start();