Masstransit EndpointConvention Azure 服务总线

Ste*_*han 3 masstransit

我想知道我是否做错了什么,我希望MassTransit会自动ReceiveEndpointsEndpointConvention.

示例代码:

services.AddMassTransit(x =>
{
    x.AddServiceBusMessageScheduler();
    x.AddConsumersFromNamespaceContaining<MyNamespace.MyRequestConsumer>();
    x.UsingAzureServiceBus((context, cfg) =>
    {
        // Load the connection string from the configuration.
        cfg.Host(context.GetRequiredService<IConfiguration>().GetValue<string>("ServiceBus:ConnectionString"));
        cfg.UseServiceBusMessageScheduler();

        // Without this line I'm getting an error complaining about no endpoint convention for x could be found.
        EndpointConvention.Map<MyRequest>(new Uri("queue:queue-name"));

        cfg.ReceiveEndpoint("queue-name", e =>
        {
            e.MaxConcurrentCalls = 1;
            e.ConfigureConsumer<MyRequestConsumer>(context);
        });

        cfg.ConfigureEndpoints(context);
    });
});
Run Code Online (Sandbox Code Playgroud)

我认为EndpointConvention.Map<MyRequest>(new Uri("queue:queue-name"));在不指定队列名称的情况下允许发送到总线不需要这条线,或者我错过了什么?

await bus.Send<MyRequest>(new { ...});

Chr*_*son 15

EndpointConvention是一种方便的方法,它允许在不指定端点地址的情况下使用Send。MassTransit 中没有任何东西会自动配置它,因为坦率地说,我不使用它。而且我认为其他人也不应该这样做。也就是说,人们确实出于任何原因使用它。

首先,考虑一下后果——如果每个消息类型都注册为端点约定,那么在多个端点上发布和使用的消息呢?那行不通。

因此,如果您想按消息类型路由消息,MassTransit 有一个功能。它被称为Publish并且效果很好。

但是等等,这是一个命令,命令应该是Sent

确实如此,但是,如果您控制应用程序并且您知道您的代码库中只有一个消费者使用KickTheTiresAndLightTheFires消息合约,那么发布与发送一样好,您不需要知道地址!

不,老兄,我想使用发送!

好的,好的,这是细节。使用 ConfigureEndpoints() 时,MassTransit 使用IEndpointNameFormatter生成基于通过、 等注册的类型的接收端点队列名称AddConsumerAddSagaStateMachine如果您想在不指定目标地址的情况下使用Send,则可以使用相同的接口来注册您自己的端点约定.

当然,您将消费者和消息类型的知识结合起来,但这是您的要求。您已经在处理魔法(通过使用没有明确目的地的发送)那么为什么不正确呢?

string queueName = formatter.Consumer<T>()
Run Code Online (Sandbox Code Playgroud)

将该字符串用于该使用者中的消息类型作为$"queue:{queueName}"地址并将其注册到 EndpointConvention 上。

或者,您知道,只需使用Publish.

  • 我认为如果没有订阅者,“发送”和“发布”之间的语义是不同的:如果我在没有订阅者的情况下发布,消息将被丢弃。即使当前没有订阅者,“发送”也会将消息保留在目标队列中。 (6认同)
  • 我有点困惑,因为你的官方文档说“不要使用发布命令”&gt;&gt; https://masstransit-project.com/usage/messages.html#message-names &lt;&lt; (5认同)
  • 好吧,在这种情况下,文档是错误的。 (5认同)
  • 如上所述,做出这个决定时要小心。1 - 如果消费者总线没有在生产者之前启动,则发布的“命令”将会丢失。2 - 如果发布“命令”,并且同一条消息有多个使用者,则可能会多次处理相同的命令。3 - 对于您发布的每个“命令”,您将获得一个额外的交换/主题。如有错误请指正。 (4认同)
  • @ChrisPatterson 很抱歉对此进行了挖掘,但我感觉“发布”需要*一些*额外的配置。如果我添加使用者,但不注册接收端点,则该消息永远不会被消耗...... (2认同)