我正在不断地以窥视模式接收消息,如果处理失败(而不是交付),则放弃它们。但是,该消息立即再次可用并被接收以进行处理。它再次快速失败,并在最大交付次数之后被发送到死信队列。
是否有一种方法可以配置主题/订阅,在消息被放弃后等待一段时间才释放它?最好呈指数方式增加等待时间。
当然,我也可以通过代码进行建议。
我正在不断地以窥视模式接收消息,如果处理失败(而不是交付),则放弃它们。但是,该消息立即再次可用并被接收以进行处理。它再次快速失败,并在最大交付次数之后被发送到死信队列。
是否有一种方法可以配置主题/订阅,在消息被放弃后等待一段时间才释放它?最好呈指数方式增加等待时间。
当然,我也可以通过代码进行建议。
Service Bus配置中没有设置指数退避的方法。我曾经遇到过相同的问题,采取了以下措施:
我们将Service Bus消息队列有效载荷封装在一个指定了传送尝试次数的类中。我们将传送尝试次数乘以一个常数,然后将该数字加到当前时间日期以便在未来进行计划交付。超过我们想要尝试的传送尝试次数后,我们明确地将消息存入死信。
编辑于7-17-2020 考虑使用Azure可靠任务框架,该框架具有可自定义的重试策略。
你可以使用定时消息来实现这个功能。
基本上,当你需要重试一条消息时,只需将其安排在未来的某个时间,Service Bus 就会在足够的时间过去后再次将其添加到队列中:
ServiceBusSender queue = ...
int secs = // calculate the delay
var msg = new ServiceBusMessage("My scheduled message body")
{
ApplicationProperties =
{
["RetryCount"] = retryCount,
},
};
logger.LogInformation("Scheduling for " + secs + " secs");
await queue.ScheduleMessageAsync(msg, DateTimeOffset.Now.AddSeconds(secs));
您必须在标题或正文中添加有关重试计数的信息,否则您将不知道尝试了多少次,并且无法真正计算未来的日期。
另一个选择是使用MassTransit,它支持Azure Service Bus。
看一下它广泛的重试配置。
请注意,MassTransit在接收到消息后实际上是在内存中执行重试,因此您需要适当调整主题订阅的MaxDeliveryCount
和MaxAutoRenewDuration
设置。
您的配置可能如下所示:
var busControl = Bus.Factory.CreateUsingAzureServiceBus(cfg =>
{
var host = cfg.Host(serviceBusConnectionString, hst => { });
cfg.UseMessageRetry(retryConfigurator =>
RetryConfigurationExtensions.Exponential(retryConfigurator, ...);
cfg.SubscriptionEndpoint(
"subscriptionName",
"topicPath",
e =>
{
e.Consumer<SomeConsumer>();
// Let MassTransit do the retries
e.MaxDeliveryCount = 1;
e.MaxAutoRenewDuration = TimeSpan.FromMinutes(10);
});
});
我也在研究这个话题,我发现 Microsoft 公司的 RetryExponential 类。
RetryExponential 类
命名空间:Microsoft.ServiceBus
程序集:Microsoft.ServiceBus.dll表示重试策略的实现。每次必须重新尝试消息操作时,重试间隔以交错指数方式增长。
public sealed class RetryExponential : Microsoft.ServiceBus.RetryPolicy