我一直在以peek模式接收消息,并在处理失败时放弃它们(不是交付)。但是,该消息立即再次可用,并再次收到处理。它再次快速失败,在最大交付后,它已经死了。
有没有办法将主题/订阅配置为在放弃后释放邮件之前等待?最好是以指数方式。
当然,我也可以通过代码获取建议。
答案 0 :(得分:1)
无法在Service Bus配置中设置指数退避。我遇到了同样的问题,并做了以下工作:
我们将Service Bus Message Queue有效负载包装在一个指定传递尝试次数的类中。我们将传递尝试次数乘以常量,然后将该数字添加到当前日期时间以便将来计划传递。在超出我们想要尝试的传递尝试次数之后,我们明确地将该消息写入死信。
答案 1 :(得分:0)
另一个选择是使用MassTransit,它支持Azure Service Bus。
看看它广泛的retry configuration。
请注意,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);
});
});
答案 2 :(得分:-1)
我也在研究这个主题,并且遇到了Microsoft的RetryExponential类。
RetryExponential类
命名空间:Microsoft.ServiceBus
程序集:Microsoft.ServiceBus.dll表示重试策略的实现。每次必须重试消息传递操作时,重试之间的延迟都会以交错的指数方式增长。
from django.db import models from django.urls import reverse class Category(models.Model): name = models.CharField(max_length=200, db_index=True) slug = models.SlugField(max_length=200, db_index=True, unique=True) class Meta: ordering = ('name',) verbose_name = 'category' verbose_name_plural = 'categories' def __str__(self): return self.name def get_absolute_url(self): return reverse('shop:product_list_by_category', args=[self.slug]) class Product(models.Model): category = models.ForeignKey(Category, related_name='products', on_delete=True) name = models.CharField(max_length=200, db_index=True) slug = models.SlugField(max_length=200, db_index=True, unique=True) image = models.ImageField(upload_to='products/%y/%m/%d', blank=True) description = models.TextField(blank=True) price = models.DecimalField(max_digits=10, decimal_places=2) stock = models.PositiveIntegerField() available = models.BooleanField(default=True) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now_add=True) class Meta: ordering = ('-created',) index_together = (('id', 'slug'),) def __str__(self): return self.name