我有一个处理销售交易的 ServiceBusTrigger 方法。如果在数据库中找不到事务并返回 404,我将复制服务总线消息并在应用程序属性中添加/增加 retryCounter。当达到最大重试次数时,我将其写入死信。
我的问题是,我需要一种方法来从 serviceBusReceived 消息中删除 retryCounter,或者能够将其设置回零,以便可以重新提交消息。
这是我目前的逻辑。
` catch (Exception ex) when (ex.Message.Contains("Not Found")) { 整数重试 = 0;
var parsedMessage = _messageReceiver.ParseServiceBusMessage(message);
// create new sb message and retrieve retry count
var newMessage = new ServiceBusMessage(message);
newMessage.ApplicationProperties.TryGetValue("RetryCount", out object retry);
if (retry != null)
retries = Convert.ToInt32(retry);
// retry less than max count - increment count, submit new msg to service bus, complete previous sb message
if (retries < _config.MaxRetryCount)
{
var msgSuffix = DateTime.Now.ToString("yyyy-MM-dd H:mm:ss.FFFFFF");
newMessage.MessageId = $"{parsedMessage.Transaction} {msgSuffix}";
if (!newMessage.ApplicationProperties.ContainsKey("RetryCount"))
newMessage.ApplicationProperties.Add("RetryCount", (retries + 1).ToString());
else
{
newMessage.ApplicationProperties.Remove("RetryCount");
newMessage.ApplicationProperties.Add("RetryCount", (retries + 1).ToString());
}
newMessage.ScheduledEnqueueTime = DateTime.UtcNow.AddSeconds(_config.HoldServiceBusMsgMinutes);
await outputEvents.AddAsync(newMessage);
log.LogInformation("Transaction not found. Resubmitted to service bus {transaction}", parsedMessage.Transaction);
await _messageReceiver.CompleteMessageAsync(message, messageReceiver);
}
// max retries reached - deadletter the service bus message
else
{
log.LogError("Transaction number {transaction} has reached max number of 404 retries", parsedMessage.Transaction);
await _messageReceiver.DeadletterMessageAsync(message, messageReceiver, ex);
}
}
`
我在ServiceBusReceived.ApplicationProperties中寻找Remove()方法,或者寻找更新属性的方法,但我相信它们是只读的。有没有另一种方法可以让消息在没有计数器的情况下变成死信,或者至少更新为零?谢谢您的任何建议。
服务总线消息对于消费者来说是不可变的。 发布后,消息唯一可能发生的更改是代理拥有的字段,例如LockedUntil。 每次根据当前代理状态读取消息时,都会动态填充这些内容。
因此,无法按照您想要的方式管理重试计数应用程序属性 - 除非您愿意克隆消息并发布具有更新值的副本。
对于这种特定场景,您可能需要考虑使用 DeliveryCount,它是代理拥有的属性,每次在显式放弃或由于锁定过期后收到消息时,该属性都会增加 1。
事实上,如果您的目标是重试多次后出现死信,服务总线可以通过“最大交付计数”设置隐式地为您管理此操作。 您的应用程序只需决定是在成功时完成还是在失败时放弃。 更多讨论可以在将消息移至 DLQ 中找到。