【问题标题】:What kind of exceptions give retries in Azure Service Bus SubscriptionClient?在 Azure 服务总线 SubscriptionClient 中,哪些异常会导致重试?
【发布时间】:2020-02-08 03:16:16
【问题描述】:

我正在为消息太快进入死信队列而苦苦挣扎。我已经指定了这样的 ExponentialRetry 策略:

        private readonly RetryExponential _retryPolicy = new RetryExponential(
            TimeSpan.FromSeconds(1),
            TimeSpan.FromMinutes(20),
            10);

当 SQL Server 暂时关闭 ("because its replica role is RESOLVING which does not allow connections. Try the operation again later.") 时,消息将在死信队列中结束 重试。

我该怎么做才能重试?

我查看了the source code for the SDK,似乎只有短暂的 ServiceBusException 才会重试,但我觉得这很奇怪。

更新:

在与我的同事讨论并在 Application Insights 中查看更多信息后,我可以看到它实际上已经重试了 10 次,但都在 2 秒内完成。这是在订阅本身上设置的最大传递计数,而不是在客户端上。此交付不受我想要和需要的任何指数退避的影响。

【问题讨论】:

    标签: azureservicebus azure-servicebus-queues


    【解决方案1】:

    我查看了 SDK 的源代码,似乎只有瞬态 ServiceBusException 会重试,但我觉得这很奇怪。

    这是正确的,符合设计。当错误是暂时性错误(连接问题、限制等)时,客户端将使用RetryPolicy 重试。否则,重试无济于事,因此重试相同的操作也无济于事。

    根据您的具体情况 - 执行您的代码并处理消息。客户和经纪人之间没有问题。这就是政策没有生效的原因。此外,您确认这是一个应用程序问题,因为您的进程重试了消息并最终进入死信队列。

    我正在为消息太快进入死信队列而苦苦挣扎。

    您需要的是应用程序重试和回退,以确保不会立即多次重试消息,从而导致消息出现死信。这部分可能有点棘手,具体取决于您的 SQL 服务器关闭了多长时间。有几个选项:

    1. 将消息安排在以后让 SQL Server 恢复。此选项需要安排新消息。
    2. 推迟消息并稍后处理。这意味着您需要保留延迟消息SequenceNumbers 的记录。实现此选项的一种方法是使用原始消息的序列号安排新消息。
    3. 在服务总线之上使用抽象,提供高级概念/功能来执行重试,例如MassTransit 或 NServiceBus (Recoverability)。

    【讨论】:

    • 是否可以在 ServiceBusExceptions 中包装我自己的(瞬态)异常,将 IsTransient 设置为 true?也许更正确的处理是从订阅自动转发到我收听的队列。当发生特定于应用程序的瞬态异常时,将相同的消息放回队列中,安排在未来,并使用自定义消息属性来处理重试次数和回退时间。
    • 不,这是不可能的。 ServiceBusExceptions 由代理引发,而不是自定义代码。你将如何处理它取决于你。只要不超过MaxDeliveryCount,消息就不会是死信。
    猜你喜欢
    • 1970-01-01
    • 2015-02-25
    • 2015-06-26
    • 2018-12-17
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多