如何在重试使用 Polly 之前记录一些东西?

How to log something before retry using Polly?

我正在尝试在 .net 核心网络 api.

中使用 Polly 重试网络 api 调用之前记录一些内容

我知道网络 api 出现故障并返回 503 响应代码,但是作为重试调用的一部分,我的控制台日志中没有任何内容。知道为什么以及如何解决这个问题吗?

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .Or<SocketException>()
    .WaitAndRetryAsync(new[]
    {
        TimeSpan.FromSeconds(2),
        TimeSpan.FromSeconds(5),
        TimeSpan.FromSeconds(10)
    }, (exception, timeSpan, retryCount, context) =>
    {
        Console.Write("RETRYING - " + DateTime.Now.Second);
    });

await retryPolicy.ExecuteAsync(async () =>
{
    var serviceReturnLabel = await this.stockTransfersServiceClient.GetPRReturnLabel(ItemSourceType.ReturnLocker);

    if (serviceReturnLabel != null && serviceReturnLabel.Accepted)
    {
        returnLabel = serviceReturnLabel.PRLabel;
    }
});

重试策略公开了一个挂钩,您可以在其中连接自定义代码,该代码将在重试 惩罚 之前调用。换句话说,每当应触发策略但在两次尝试之间等待之前,将调用此委托。

此挂钩称为 onRetryonRetryAsync,具体取决于您的策略是同步还是异步。

在这里您可以看到何时调用这些用户定义的自定义委托:


所以,你已经连接到正确的钩子了。

现在您必须确保触发了策略。您可以使用 Console.Write 或某些记录器将信息从您的委托推送到标准输出。

或者您可以简单地在匿名 lambda 委托中设置一个断点,以确保它在调试期间被调用。


如果没有调用,则必须检查以下内容:

  • 是否处理了抛出的异常?
  • 有没有例外?

从策略的角度来看,可以有两种异常:已处理和未处理。如果尚未达到阈值,前者可以触发新的尝试。后者不会触发另一次尝试,而是会重新抛出原始异常。 (Reference)

在您的情况下,策略已设置为在抛出 HttpRequestExceptionSocketException 时触发。如果抛出的异常是其中的 none 个,那么从策略的角度来看,它被认为是未处理的。

如果没有异常,您的保单将不会被触发。有一个典型的错误我们已经犯过好几次了。假设我们期望 http 响应应该是 200。只要不成功,我们就想发出重试。如果响应不成功,我们可能会使用 HandleTransientHttpError (Ref) extension. But that extension watches only the 408 and 5xx status codes. So if we receive for example 429 (too many requests) then no retry will happen. We have to explicitly call the EnsureSuccessStatusCode (Ref) 方法抛出错误。