This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

重试和退避弹性策略

配置重试和退避的弹性策略

1 - 重试弹性策略

为重试配置弹性策略

请求可能因瞬时错误而失败,例如遇到网络拥塞、重新路由到过载实例等。有时,请求也可能因已设置的其他弹性策略而失败,例如触发了定义的超时或熔断器策略。

在这些情况下,配置 retries 可以:

  • 将相同请求发送到不同的实例,或
  • 在条件清除后重试发送请求。

重试和超时协同工作,超时确保您的系统在需要时快速失败,而重试从临时故障中恢复。

Dapr 提供默认弹性策略,您可以使用用户定义的重试策略覆盖它们。

重试策略格式

示例 1

spec:
  policies:
    # Retries are named templates for retry configurations and are instantiated for life of the operation.
    retries:
      pubsubRetry:
        policy: constant
        duration: 5s
        maxRetries: 10

      retryForever:
        policy: exponential
        maxInterval: 15s
        maxRetries: -1 # Retry indefinitely

示例 2

spec:
  policies:
    retries:
      retry5xxOnly:
        policy: constant
        duration: 5s
        maxRetries: 3
        matching:
          httpStatusCodes: "429,500-599" # retry the HTTP status codes in this range. All others are not retried. 
          gRPCStatusCodes: "1-4,8-11,13,14" # retry gRPC status codes in these ranges and separate single codes.

规范元数据

以下重试选项是可配置的:

重试选项描述
policy确定退避和重试间隔策略。有效值为 constantexponential
默认为 constant
duration确定重试之间的时间间隔。仅适用于 constant 策略。
有效值为 200ms15s2m 等格式。
默认为 5s
maxInterval确定exponential 退避策略可以增长到的重试之间的最大间隔。
额外的重试总是在 maxInterval 的持续时间后发生。默认为 60s。有效值为 5s1m1m30s 等格式。
maxRetries要尝试的最大重试次数。
-1 表示无限次重试,而 0 表示不会重试请求(本质上表现为未设置重试策略)。
默认为 -1
matching.httpStatusCodes可选:逗号分隔的要重试的 HTTP 状态码或状态码范围字符串。未列出的状态码不会被重试。
有效值:100-599,参考
格式:<code> 或范围 <start>-<end>
示例:“429,501-503”
默认:空字符串 "" 或未设置字段。重试所有 HTTP 错误。
matching.gRPCStatusCodes可选:逗号分隔的要重试的 gRPC 状态码或状态码范围字符串。未列出的状态码不会被重试。
有效值:0-16,参考
格式:<code> 或范围 <start>-<end>
示例:“4,8,14”
默认:空字符串 "" 或未设置字段。重试所有 gRPC 错误。

指数退避策略

指数退避窗口使用以下公式:

BackOffDuration = PreviousBackOffDuration * (Random value from 0.5 to 1.5) * 1.5
if BackOffDuration > maxInterval {
  BackoffDuration = maxInterval
}

重试状态码

当应用程序跨越多个服务时,特别是在像 Kubernetes 这样的动态环境中,服务可能因各种原因而消失,网络调用可能会开始挂起。状态码提供了对我们操作的洞察以及它们在生产中可能失败的位置。

HTTP

下表包含您可能收到的一些 HTTP 状态码示例,以及您是否应该或不应该重试某些操作。

HTTP 状态码建议重试?描述
404 Not Found❌ 否资源不存在。
400 Bad Request❌ 否您的请求无效。
401 Unauthorized❌ 否尝试获取新凭据。
408 Request Timeout✅ 是服务器等待请求超时。
429 Too Many Requests✅ 是(如果存在,请遵守 Retry-After 头)。
500 Internal Server Error✅ 是服务器遇到意外情况。
502 Bad Gateway✅ 是网关或代理接收到无效响应。
503 Service Unavailable✅ 是服务可能会恢复。
504 Gateway Timeout✅ 是临时网络问题。

gRPC

下表包含您可能收到的一些 gRPC 状态码示例,以及您是否应该或不应该重试某些操作。

gRPC 状态码建议重试?描述
Code 1 CANCELLED❌ 否N/A
Code 3 INVALID_ARGUMENT❌ 否N/A
Code 4 DEADLINE_EXCEEDED✅ 是使用退避重试
Code 5 NOT_FOUND❌ 否N/A
Code 8 RESOURCE_EXHAUSTED✅ 是使用退避重试
Code 14 UNAVAILABLE✅ 是使用退避重试

基于状态码的重试过滤器

重试过滤器允许通过指定应应用重试的 HTTP 和 gRPC 状态码或范围,对重试策略进行细粒度控制。

spec:
  policies:
    retries:
      retry5xxOnly:
        # ...
        matching:
          httpStatusCodes: "429,500-599" # retry the HTTP status codes in this range. All others are not retried. 
          gRPCStatusCodes: "4,8-11,13,14" # retry gRPC status codes in these ranges and separate single codes.

演示

观看 Diagrid 的 Dapr v1.15 庆祝活动期间演示的演示,了解如何使用 Diagrid Conductor 设置重试状态码过滤器。

后续步骤

相关链接

尝试其中一个弹性快速入门:

2 - 覆盖默认重试弹性策略

了解如何为特定 API 覆盖默认重试弹性策略

Dapr 为任何不成功的请求(如故障和临时错误)提供默认重试。在弹性规范中,您可以通过使用保留的命名关键字定义策略来覆盖 Dapr 的默认重试逻辑。例如,定义一个名为 DaprBuiltInServiceRetries 的策略可以覆盖通过服务间请求在边车之间发生故障时的默认重试。策略覆盖不会应用于特定目标。

注意:虽然您可以使用更稳健的重试来覆盖默认值,但不能使用低于提供的默认值的值进行覆盖,也不能完全移除默认重试。这可以防止意外的停机。

下表描述了 Dapr 的默认重试以及用于覆盖它们的策略关键字:

功能覆盖关键字默认重试行为描述
服务调用DaprBuiltInServiceRetries每次调用重试的退避间隔为 1 秒,最多重试 3 次。边车对边车的请求(服务调用方法调用)失败并导致 gRPC 代码 UnavailableUnauthenticated
ActorsDaprBuiltInActorRetries每次调用重试的退避间隔为 1 秒,最多重试 3 次。边车对边车的请求(Actor 方法调用)失败并导致 gRPC 代码 UnavailableUnauthenticated
Actor 提醒DaprBuiltInActorReminderRetries每次调用重试采用指数退避,初始间隔为 500ms,最大间隔为 60s,持续时间为 15 分钟向状态存储持久化 Actor 提醒失败的请求
初始化重试DaprBuiltInInitializationRetries每次调用执行 3 次重试,采用指数退避,初始间隔为 500ms,持续时间为 10 秒向应用程序发出请求以检索给定规范时的故障。例如,检索订阅、组件或弹性规范失败

下面的弹性规范示例展示了如何使用保留的命名关键字 ‘DaprBuiltInServiceRetries’ 来覆盖_所有_服务调用请求的默认重试。

同时还定义了一个名为 ‘retryForever’ 的重试策略,该策略仅应用于 appB 目标。appB 使用 ‘retryForever’ 重试策略,而所有其他应用程序服务调用重试故障则使用被覆盖的 ‘DaprBuiltInServiceRetries’ 默认策略。

spec:
  policies:
    retries:
      DaprBuiltInServiceRetries: # 覆盖服务间调用的默认重试行为
        policy: constant
        duration: 5s
        maxRetries: 10

      retryForever: # 用户定义的重试策略会替换默认重试。目标仅依赖于应用的策略。 
        policy: exponential
        maxInterval: 15s
        maxRetries: -1 # 无限期重试

  targets:
    apps:
      appB: # 目标服务的 app-id
        retry: retryForever

相关链接

尝试其中一个弹性快速入门: