简体   繁体   English

将公共交通配置为每个实例仅发送给一个消费者

[英]Configure mass transit to send to only one consumer per instance

I would like to use MassTransit in a way that would allow my application to have multiple consumers that are all consuming messages for the same type, but have it so that only one consumer ever receives each message.我想以一种允许我的应用程序有多个消费者的方式使用 MassTransit,这些消费者都在消费相同类型的消息,但只有一个消费者收到每条消息。 I do not care which one receives any particular message, only that it is handled once.我不在乎哪一个收到任何特定的消息,只关心它被处理一次。 Below is the code that I initially thought would work.下面是我最初认为可行的代码。

            services.AddScoped<S3ToArchiveConsumer<CaringoConfig, WasabiEastOneConfig>>();     
            services.AddScoped<S3ToArchiveConsumer<CaringoConfig, WasabiEastTwoConfig>>();           
            services.AddMassTransit(x =>
            {
                x.SetKebabCaseEndpointNameFormatter();
                x.UsingRabbitMq((context, cfg) =>
                {
                    CaringoShovelSettings caringoShovel = context.GetRequiredService<IOptions<CaringoShovelSettings>>().Value;
                    AppSettings appSettings = context.GetRequiredService<IOptions<AppSettings>>().Value;
                    cfg.Host(appSettings.RabbitMqHost, "/", h =>
                    {
                        h.Username(appSettings.RabbitMqUsername);
                        h.Password(appSettings.RabbitMqPassword);
                    });
                    if ((caringoShovel.WasabiEastOneShovel?.Enabled ?? false) || (caringoShovel.WasabiEastTwoShovel?.Enabled ?? false))
                    {
                        cfg.ReceiveEndpoint(nameof(MoveCaringoFileRequest), e =>
                        {
                            e.Durable = true;
                            e.Exclusive = false;
                            e.ExclusiveConsumer = false;
                            e.ThrowOnSkippedMessages();
                            if (caringoShovel.WasabiEastOneShovel?.Enabled ?? false)
                            {
                               
                                e.Consumer<S3ToArchiveConsumer<CaringoConfig, WasabiEastOneConfig>>(context, configure =>
                                 {
                                     configure.UseTimeout(x => x.Timeout = caringoShovel.WasabiEastOneShovel.Timeout);
                                     configure.UseConcurrentMessageLimit(caringoShovel.WasabiEastOneShovel.Concurrency);
                                 });
                            }
                            if (caringoShovel.WasabiEastTwoShovel != null && caringoShovel.WasabiEastTwoShovel.Enabled == true)
                            {
                                
                                e.Consumer<S3ToArchiveConsumer<CaringoConfig, WasabiEastTwoConfig>>(context, configure =>
                                 {
                                     configure.UseTimeout(x => x.Timeout = caringoShovel.WasabiEastTwoShovel.Timeout);
                                     configure.UseConcurrentMessageLimit(caringoShovel.WasabiEastTwoShovel.Concurrency);
                                 });
                            }
                        });
                    }
                    cfg.ConfigureEndpoints(context);
                });
            });
            services.AddMassTransitHostedService();

You didn't post the errors you are seeing, or what's coming out of the log, but there are quite a few ordering issues with the above configuration (which I've cleaned up below).您没有发布您看到的错误或日志中的内容,但是上述配置存在很多排序问题(我已在下面进行了清理)。 Also, you should ensure that every receive endpoint is configured identically, to avoid skipped messages.此外,您应该确保每个接收端点的配置都相同,以避免跳过消息。 Throwing on skipped messages could cause unrecognized messages to block the queue, which is bad, so having a single queue with multiple message types – some of which may not be consumed by consumers on that queue – can lead to issues with your configuration.抛出跳过的消息可能会导致无法识别的消息阻塞队列,这很糟糕,因此拥有具有多种消息类型的单个队列(其中一些可能不会被该队列上的使用者使用)可能会导致您的配置出现问题。 MassTransit normally moves unrecognized messages to the _skipped queue to prevent these issues. MassTransit通常会将无法识别的消息移动到_skipped队列以防止出现这些问题。

Anyway, here is the cleaned up configuration:无论如何,这是清理后的配置:


services.AddScoped<S3ToArchiveConsumer<CaringoConfig, WasabiEastOneConfig>>();
services.AddScoped<S3ToArchiveConsumer<CaringoConfig, WasabiEastTwoConfig>>();

services.AddMassTransit(x =>
{
    x.SetKebabCaseEndpointNameFormatter();

    x.UsingRabbitMq((context, cfg) =>
    {
        CaringoShovelSettings caringoShovel = context.GetRequiredService<IOptions<CaringoShovelSettings>>().Value;
        AppSettings appSettings = context.GetRequiredService<IOptions<AppSettings>>().Value;

        cfg.Host(appSettings.RabbitMqHost, "/", h =>
        {
            h.Username(appSettings.RabbitMqUsername);
            h.Password(appSettings.RabbitMqPassword);
        });

        if ((caringoShovel.WasabiEastOneShovel?.Enabled ?? false) || (caringoShovel.WasabiEastTwoShovel?.Enabled ?? false))
        {
            cfg.ReceiveEndpoint(nameof(MoveCaringoFileRequest), e =>
            {
                e.ThrowOnSkippedMessages();

                if (caringoShovel.WasabiEastOneShovel?.Enabled ?? false)
                {
                    e.ConcurrentMessageLimit = caringoShovel.WasabiEastOneShovel.Concurrency;
                    e.Consumer<S3ToArchiveConsumer<CaringoConfig, WasabiEastOneConfig>>(context, configure =>
                    {
                        configure.UseTimeout(x => x.Timeout = caringoShovel.WasabiEastOneShovel.Timeout);
                    });
                }
                if (caringoShovel.WasabiEastTwoShovel?.Enabled ?? false)
                {
                    // this may overwrite the value above if both are specified
                    e.ConcurrentMessageLimit = caringoShovel.WasabiEastTwoShovel.Concurrency;

                    e.Consumer<S3ToArchiveConsumer<CaringoConfig, WasabiEastTwoConfig>>(context, configure =>
                    {
                        configure.UseTimeout(x => x.Timeout = caringoShovel.WasabiEastTwoShovel.Timeout);
                    });
                }
            });
        }
    });
});
services.AddMassTransitHostedService();

The more I think about your question, I've come to suggest that this should be two completely separate receive endpoints, and you should publish the message using MassTransit, so that each queue receives a copy of it.我对您的问题考虑得越多,我建议这应该是两个完全独立的接收端点,并且您应该使用 MassTransit 发布消息,以便每个队列接收它的副本。 And only one consumer on each receive endpoint.每个接收端点上只有一个消费者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM