c# - 将消息移动到 azure servicebus 中的“deadletter”
问题描述
我已经实现了退避指数重试。因此,基本上,如果有任何异常,我会克隆消息,然后通过添加一些延迟将其重新提交到队列中。
现在我面临 2 个问题 - 1)当我克隆并重新提交回队列时,我发现交付计数没有增加 2)如果达到最大交付计数,我想将其移至死信。
代码 :
catch (Exception ex)
{
_logger.Error(ex, $"Failed to process request {requestId}");
var clone = messageResult.Message.Clone();
clone.ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddSeconds(45);
await messageResult.ResendMessage(clone);
if (retryCount == MaxAttempts)
{
//messageResult.dea
}
return new PdfResponse { Error = ex.ToString() };
}
请帮助我
解决方案
当您克隆一条消息时,它会变成一条新消息,这意味着系统属性不会被克隆,这会为克隆的消息提供从 1 开始的新传递计数。另见https://docs.azure.cn/zh-cn/dotnet/api/microsoft.azure.servicebus.message.clone?view=azure-dotnet
您可以查看 Azure 服务总线的Peek Lock 功能。使用 PeekLock 时,消息在队列中不可见,直到您明确放弃它(将其放回队列并增加传递计数)或在处理消息时一切按预期工作时完成。另一种选择是明确地死信这条消息。
但重要的是,如果您不执行上述任何操作(例如克隆), Azure 服务总线将在定义的时间间隔(LockDuration 属性)或您放弃它时自动使消息再次可见。
因此,要获得延迟重试和死信行为(当达到最大传递计数时),您可以使用以下选项:
选项 1. 通过 Azure 服务总线自动解锁重试
当由于某种原因暂时无法执行消息处理时,捕获异常并确保没有执行任何提到的操作(放弃、完成或死信)。这将使消息在剩余时间内保持不可见,并在达到配置的锁定持续时间后使其再次可见。Azure 服务总线也将按预期增加交付计数。
选项 2. 实施您自己的重试策略
在您的代码中执行您自己的重试策略并重试处理消息。如果已达到最大重试次数,请放弃该消息,在达到重试时间后,该消息将在下一个队列读取步骤中再次可见。在这种情况下,交货计数也会增加。
注意:如果您选择选项 2.) 确保您的重试周期符合定义的 LockDuration,这样如果您仍在重试处理它,您的消息将不会再次出现在队列中。您还可以通过在重试之间的消息上调用RenewLock()方法来更新重试之间的锁。
如果您在代码中实施重试策略,我建议您使用Polly .Net,它已经为您提供了强大的功能,例如重试和断路器策略。见https://github.com/App-vNext/Polly
推荐阅读
- java - 添加后如何对数字进行四舍五入以避免不必要的数字
- mysql - 如何使用mysql从到期条目中获取待处理的月份
- c++ - 如何在一个循环中分离两个不同的数组?
- c# - 为什么我的项目中出现 Newtonsoft.Json.JsonConvert 的 CS0433 错误?
- twig - 如何打印组 ID
- android - 如何使片段等待Android Kotlin中的当前位置
- entity-framework-core - 无法使用 EF Core 3.0 CosmosDb 提供程序连接到 Azure Cosmos Db 帐户(Core SQL API)
- kubernetes - 如何使用部署在 Kubernetes 上的服务的延迟来扩展部署?
- jquery - css3 旋转动画——开始旋转,然后停在帧上
- c++11 - 如何更改元组中对象的值?