问题
I've been looking at MassTransit for a couple of weeks now and I'm curious about the possibilities. However, I don't seem to be able to get the concepts quite right.
Expected behaviour I wanted to publish message to "direct" exchange with routing key which is bind to two different queue for performing other activities.
When I attempted the same logic using MassTransit for better scalability. I've found MassTransit creates own exchange based on queue name with fanout type.
Classic code to publish message by exchange and 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);
}
}
Is there a way to configure direct or topic exchange with routingkey in MassTransit?
回答1:
This is not a supported scenario with MassTransit. MassTransit will always create a fanout queue. If you managed your topology yourself, you can use IEndpoint.Send
to directly send the message to the exchange you created. In this case you give up much what MT provides though.
I'm also not sure what "better scalability" means in this case. Fanout exchanges perform better than direct exchanges (in most cases) since there's no routing logic that needs to be processed.
Maybe if you clarified your performance concerns on the MassTransit mailing list we could help you a bit more there.
回答2:
MassTransit handles publish and subscribe without using topic exchanges, instead creating exchanges for the message types being published, and binding those exchanges to the consumer queues.
The routing key approach is less efficient with RabbitMQ, which prefers to use the exchange fabric for message routing simplicity (no hash tables to maintain).
Instead of dealing with exchanges and routing keys, just define your command and/or event types, and the send or publish those messages and let the consumers do their work.
回答3:
Following code does the same work, but with one extra fanout exchange:
TestMessage (direct exchange) -> TestMessage_Queue(fanout exchange) -> TestMessage_Queue (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();
来源:https://stackoverflow.com/questions/30147212/publish-message-using-exchange-and-routing-key-using-masstransit