Http 客户端的重试策略

问题描述 投票:0回答:1

如何改进此代码,以便重试适用于默认情况下需要重试的所有异常

public static readonly AsyncPolicy RetryPolicy = Policy
   .Handle<Exception>()
   .RetryAsync(3);

c# .net dotnet-httpclient polly retry-logic
1个回答
0
投票

例外情况

SendAsync
操作会抛出以下异常

  • ArgumentNullException
    当请求是
    null

  • InvalidOperationException
    当请求消息已由 HttpClient 实例发送时

  • HttpRequestException
    当请求由于网络连接、DNS 故障、服务器证书验证或超时等根本问题而失败时

  • TaskCanceledException
    当请求因超时而失败时(仅限 .NET Core 和 .NET 5 及更高版本

  • OperationCanceledException

    取消令牌被取消时(
    此异常存储到返回的任务中

重试前两个异常不会改变结果。它仍然会失败并出现完全相同的异常。这些异常表明调用方存在问题。

TaskCanceledException

源自OperationCanceledException
。因此,如果您想在这两种情况下重试,那么只处理后一种就足够了。

public static readonly AsyncPolicy RetryPolicy = Policy .Handle<HttpRequestException>() .Or<OperationCanceledException>() .RetryAsync(3);
状态代码

以上部分仅涵盖了

SendAsync

 因异常而失败的情况。但也可能存在 
SendAsync
 没有失败但发送的请求没有被处理的情况。 
SendAsync
 返回一个 
HttpResponseMessage
 对象,其 
StatusCode
 属性可能指示可重试的问题。典型的可重试状态代码:

    408 请求超时
  • 429 请求太多
  • (500内部服务器错误)
  • 502 网关错误
  • 503 服务不可用
  • 504 网关超时
内部服务器错误通常被视为可重试的状态代码,但它实际上取决于下游系统的实现。您可能调用了有错误的端点。重新发出相同的请求很可能不会导致与 500 不同的状态代码。


如果您查看

AddTransientHttpErrorPolicy

备注,那么您可以看到它将注册一个重试策略,该策略会在以下条件之一触发:

    网络故障(如
  • HttpRequestException
  • HTTP 5XX 状态代码(服务器错误)
  • HTTP 408状态码(请求超时)
这可能是一个很好的起点,但您可以使用上述异常和/或状态代码之一来扩展触发器。

幂等操作

请记住,并非所有操作都可以重试。创建新资源的请求(通常是 REST 中的 POST 请求)可能会导致不必要的重复。如果下游系统没有准备好重复数据删除,那么您应该尽量避免重试。

这里我已经详细介绍了重试的注意事项。

© www.soinside.com 2019 - 2024. All rights reserved.