如何将相同的队列属性设置 (TTL) 应用于所有 AWS SQS 队列?

How to apply the same queue attribute setting (TTL) to all AWS SQS queues?

我正在尝试为我们系统中的所有 AWS SQS 队列设置相同的 TTL。

我找到了可以为错误和 DLQ 队列执行此操作的代码:

cfg.SendTopology.ConfigureErrorSettings = settings => settings.QueueAttributes.Add(QueueAttributeName.MessageRetentionPeriod, 1209600);
cfg.SendTopology.ConfigureDeadLetterSettings = settings => settings.QueueAttributes.Add(QueueAttributeName.MessageRetentionPeriod, 1209600);

但我找不到与普通队列相同的内容。 我试过了,但没用:

cfg.QueueAttributes.Add(QueueAttributeName.MessageRetentionPeriod, 1209600);

这是我的完整 MassTransit 设置:

services.AddMassTransit(x =>
{
    x.AddAmazonSqsMessageScheduler();
    x.AddConsumers(assembliesWithConsumers.ToArray());
    x.UsingAmazonSqs((context, cfg) =>
    {
        cfg.UseAmazonSqsMessageScheduler();

        cfg.Host("aws", h =>
        {
            if (!String.IsNullOrWhiteSpace(mtSettings.AccessKey))
            {
                h.AccessKey(mtSettings.AccessKey);
            }

            if (!String.IsNullOrWhiteSpace(mtSettings.SecretKey))
            {
                h.SecretKey(mtSettings.SecretKey);
            }

            h.Scope($"{mtSettings.Prefix}-{mtSettings.Environment}", true);
            var sqsConfig = !String.IsNullOrWhiteSpace(mtSettings.SqsServiceUrl)
                ? new AmazonSQSConfig() { ServiceURL = mtSettings.SqsServiceUrl }
                : new AmazonSQSConfig()
                    { RegionEndpoint = RegionEndpoint.GetBySystemName(mtSettings.Region) };

            h.Config(sqsConfig);

            var snsConfig = !String.IsNullOrWhiteSpace(mtSettings.SnsServiceUrl)
                ? new AmazonSimpleNotificationServiceConfig()
                    { ServiceURL = mtSettings.SnsServiceUrl }
                : new AmazonSimpleNotificationServiceConfig()
                    { RegionEndpoint = RegionEndpoint.GetBySystemName(mtSettings.Region) };

            h.Config(snsConfig);
        });

        cfg.QueueAttributes.Add(QueueAttributeName.MessageRetentionPeriod, 1209600);
        cfg.SendTopology.ConfigureErrorSettings = settings => settings.QueueAttributes.Add(QueueAttributeName.MessageRetentionPeriod, 1209600);
        cfg.SendTopology.ConfigureDeadLetterSettings = settings => settings.QueueAttributes.Add(QueueAttributeName.MessageRetentionPeriod, 1209600);

        cfg.ConfigureEndpoints(context, new BusEnvironmentNameFormatter(mtSettings.Environment));
    });
});

我测试了上面的代码(通过删除和重新创建队列),我可以看到错误队列是使用更新的 TTL 正确创建的,但是正常队列没有更新该设置。

如何在一个地方为所有 SQS 队列设置相同的队列属性 (TTL)?

您可以注册一个在 ConfigureEndpoints 配置接收端点时调用的委托,并在该回调中设置队列属性。

Note that error/dead-letter queues automatically copy the queue attributes of the queue

相关代码改动如下所示。

services.AddMassTransit(x =>
{
    x.AddAmazonSqsMessageScheduler();
    x.AddConsumers(assembliesWithConsumers.ToArray());

    x.AddConfigureEndpointsCallback((name, cfg) =>
    {
        if(cfg is IAmazonSqsReceiveEndpointConfigurator configurator)
        {
            configurator.QueueAttributes.Add(QueueAttributeName.MessageRetentionPeriod, 1209600);
        }
    });

    x.UsingAmazonSqs((context, cfg) =>
    {
        cfg.UseAmazonSqsMessageScheduler();

        cfg.Host("aws", h =>
        {
            if (!String.IsNullOrWhiteSpace(mtSettings.AccessKey))
            {
                h.AccessKey(mtSettings.AccessKey);
            }

            if (!String.IsNullOrWhiteSpace(mtSettings.SecretKey))
            {
                h.SecretKey(mtSettings.SecretKey);
            }

            h.Scope($"{mtSettings.Prefix}-{mtSettings.Environment}", true);
            var sqsConfig = !String.IsNullOrWhiteSpace(mtSettings.SqsServiceUrl)
                ? new AmazonSQSConfig() { ServiceURL = mtSettings.SqsServiceUrl }
                : new AmazonSQSConfig()
                    { RegionEndpoint = RegionEndpoint.GetBySystemName(mtSettings.Region) };

            h.Config(sqsConfig);

            var snsConfig = !String.IsNullOrWhiteSpace(mtSettings.SnsServiceUrl)
                ? new AmazonSimpleNotificationServiceConfig()
                    { ServiceURL = mtSettings.SnsServiceUrl }
                : new AmazonSimpleNotificationServiceConfig()
                    { RegionEndpoint = RegionEndpoint.GetBySystemName(mtSettings.Region) };

            h.Config(snsConfig);
        });

        cfg.ConfigureEndpoints(context, new BusEnvironmentNameFormatter(mtSettings.Environment));
    });
});