使用交换和路由密钥使用 MassTransit 发布消息
Publish message using exchange and routing key using MassTransit
我已经关注 MassTransit 几个星期了,我对它的可能性很好奇。但是,我似乎无法完全正确地理解这些概念。
预期行为
我想使用路由密钥将消息发布到 "direct" 交换,路由密钥绑定到两个不同的队列以执行其他活动。
当我尝试使用 MassTransit 实现相同的逻辑以获得更好的可扩展性时。我发现 MassTransit 根据具有扇出类型的队列名称创建自己的交换。
通过exchange和routing key发布消息的经典代码
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
直接将消息发送到您创建的交换。在这种情况下,您会放弃很多 MT 提供的功能。
我也不确定 "better scalability" 在这种情况下是什么意思。扇出交换比直接交换执行得更好(在大多数情况下),因为没有需要处理的路由逻辑。
也许如果您在 MassTransit mailing list 上澄清了您的性能问题,我们可以在那里为您提供更多帮助。
MassTransit 在不使用主题交换的情况下处理发布和订阅,而是为发布的消息类型创建交换,并将这些交换绑定到消费者队列。
RabbitMQ 的路由键方法效率较低,它更喜欢使用交换结构来简化消息路由(无需维护哈希表)。
无需处理交换和路由键,只需定义您的命令 and/or 事件类型,然后发送或发布这些消息并让消费者完成他们的工作。
下面的代码做同样的工作,但有一个额外的扇出交换:
TestMessage(直接交换)-> TestMessage_Queue(扇出交换)-> TestMessage_Queue(队列)
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();
我已经关注 MassTransit 几个星期了,我对它的可能性很好奇。但是,我似乎无法完全正确地理解这些概念。
预期行为 我想使用路由密钥将消息发布到 "direct" 交换,路由密钥绑定到两个不同的队列以执行其他活动。
当我尝试使用 MassTransit 实现相同的逻辑以获得更好的可扩展性时。我发现 MassTransit 根据具有扇出类型的队列名称创建自己的交换。
通过exchange和routing key发布消息的经典代码
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
直接将消息发送到您创建的交换。在这种情况下,您会放弃很多 MT 提供的功能。
我也不确定 "better scalability" 在这种情况下是什么意思。扇出交换比直接交换执行得更好(在大多数情况下),因为没有需要处理的路由逻辑。
也许如果您在 MassTransit mailing list 上澄清了您的性能问题,我们可以在那里为您提供更多帮助。
MassTransit 在不使用主题交换的情况下处理发布和订阅,而是为发布的消息类型创建交换,并将这些交换绑定到消费者队列。
RabbitMQ 的路由键方法效率较低,它更喜欢使用交换结构来简化消息路由(无需维护哈希表)。
无需处理交换和路由键,只需定义您的命令 and/or 事件类型,然后发送或发布这些消息并让消费者完成他们的工作。
下面的代码做同样的工作,但有一个额外的扇出交换:
TestMessage(直接交换)-> TestMessage_Queue(扇出交换)-> TestMessage_Queue(队列)
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();