重试 (Retry)
gRPC 消除了失败的压力!通过 OpenCensus 和 OpenTelemetry 支持,获得精细化的重试控制和详细的洞察。
概述
重试是使服务更加可靠的关键模式。通过重新尝试失败的操作,应用程序可以克服网络或服务器故障等暂时性问题。这对于现代云应用程序至关重要,帮助它们处理不可避免的瞬时故障。
最佳实践是,应用程序应了解哪些失败的操作适合重试,定义重试延迟的指数退避参数,确定重试尝试次数,并监控重试指标。
gRPC 客户端重试工作原理
gRPC 内建的重试逻辑会保存调用的历史记录,以便在需要时进行重试,并且会监控 RPC 事件。即使没有配置重试策略,gRPC 仍然会保存调用历史,以便在需要时执行透明重试(后续将讨论)。请注意,"重试" 指的是用新的调用替换失败的调用,并在新创建的调用上重放该调用的历史记录。
如果满足某些条件 —— RPC 以匹配重试策略的可重试状态码关闭,并且在重试尝试限制范围内 —— gRPC 会在指数退避延迟后创建新的重试流。
gRPC 还支持其他特性,如重试限流和服务器推送回退。有关更多详细信息,请参考 gRFC 客户端重试文档。
一旦收到响应头,RPC 就会被提交。不会再进行进一步的重试,gRPC 会将 RPC 交给应用程序。
以下是 gRPC 内部重试的架构概览:

重试配置
重试默认是启用的,但没有默认的重试策略。如果没有配置重试策略,gRPC 在大多数情况下无法安全地重试 RPC。只有由于低级竞争条件(race conditions)导致的失败才会进行重试,且仅当 gRPC 确定 RPC 没有被服务器处理时,才会进行这种 “透明重试”(transparent retry)。您可以配置重试策略,允许 gRPC 在更多情况下和更积极地进行重试。您还可以在创建通道时完全禁用重试,这将禁用透明重试及任何配置的重试策略。
透明重试
故障可能发生在不同阶段。即使没有明确的重试策略,gRPC 也可能执行透明重试。透明重试的程度取决于故障发生的时机:
|
您可以通过关注 gRPC 支持的关键步骤和配置来优化应用程序的重试功能。
-
最大重试次数
-
指数退避
-
可重试的状态码集合
重试可以通过 gRPC 服务配置进行配置,按方法粒度进行。配置包含以下选项:
"retryPolicy": {
"maxAttempts": 4,
"initialBackoff": "0.1s",
"maxBackoff": "1s",
"backoffMultiplier": 2,
"retryableStatusCodes": [
"UNAVAILABLE"
]
}
为了避免大量客户端同时对服务器造成压力,退避延迟会应用正负 20% 的抖动。在上述示例配置中,initialBackoff
设置为 100 毫秒,因此第一次重试后的实际退避延迟将在 [80ms, 120ms]
的范围内随机选择。
gRPC 支持重试的限流配置,以防止由于重试导致服务器过载。以下是重试限流配置的示例:
"retryThrottling": {
"maxTokens": 10,
"tokenRatio": 0.1
}
对于每个服务器,gRPC 客户端跟踪一个 token_count
(初始值为 maxTokens
)。失败的 RPC 会使计数减少 1,成功的 RPC 会使计数增加 tokenRatio
。如果 token_count
低于 maxTokens
的一半,重试将暂停,直到计数恢复。
此外,Hedging(请求调度)是重试的一个补充特性,并且可以类似地进行配置。有关更多详细信息,请参阅 Hedging 指南。
重试可观察性
当启用重试功能时,gRPC 支持暴露 OpenCensus 和 OpenTelemetry 度量指标。以下是 OpenTelemetry 提供的重试尝试统计信息示例:
-
grpc.client.attempt.started
-
grpc.client.attempt.duration
-
grpc.client.attempt.sent_total_compressed_message_size
-
grpc.client.attempt.rcvd_total_compressed_message_size
每个调用级别的度量指标:
-
grpc.client.call.duration
以及服务器端度量指标:
-
grpc.server.call.started
-
grpc.server.call.sent_total_compressed_message_size
-
grpc.server.call.rcvd_total_compressed_message_size
-
grpc.server.call.duration
有关深入的指标和追踪信息,以及配置说明,请参阅 gRFC 中的 Otel 指标 和 重试状态。