重试
gRPC 让您不再为故障烦恼!通过 OpenCensus 和 OpenTelemetry 支持获得精细的重试控制和详细的见解。
重试
概述
重试是使服务更可靠的关键模式。通过重新尝试失败的操作,应用程序可以克服网络或服务器故障等临时问题。这对于现代云应用程序处理不可避免的瞬态故障至关重要。
为了获得最佳实践,应用程序应了解哪些失败的操作适合重试,为重试延迟定义指数退避参数,确定重试尝试的次数,并监控重试指标。
gRPC 客户端重试的工作原理
gRPC 的内置重试逻辑会保存调用的历史记录以用于潜在的重试,并监控 RPC 事件。即使没有配置重试策略,gRPC 仍然会保存调用的历史记录,以防需要执行透明重试(稍后章节中讨论)。请注意,“重试”意味着用新的调用替换失败的调用,并在新创建的调用上重播调用的历史记录。
如果满足某些条件 – RPC 以与重试策略的可重试状态代码匹配的失败状态代码关闭,并且保持在重试尝试限制内 – gRPC 将在指数退避延迟后创建新的重试流。
gRPC 还支持其他功能,例如重试节流和服务器推送回退。有关更多详细信息,请参阅 客户端重试的 gRFC。
一旦收到响应头,RPC 就被提交。将不再尝试进一步的重试,gRPC 将 RPC 交给应用程序。
下图显示了 gRPC 重试内部的架构概述。
sequenceDiagram
Application ->> gRPC Client: Configure retry policy. <br> Send request to dns:///my-service
gRPC Client ->> gRPC Client: Save message
gRPC Client ->> Server: Create initial attempt
Server -->> gRPC Client : RPC closed with error
gRPC Client ->> Server: Create retry attempt 1
Server -->> gRPC Client: Successful
gRPC Client ->> Application: No more retry. Proceed.
重试配置
默认情况下启用重试,但没有默认的重试策略。如果没有重试策略,gRPC 在大多数情况下无法安全地重试 RPC。仅当由于底层竞争而导致 RPC 失败时才会重试,并且仅当 gRPC 确定 RPC 尚未被服务器处理时才会重试。这被称为“透明重试”。您可以配置重试策略以允许 gRPC 在更多情况下更积极地重试 RPC。您还可以在创建通道时完全禁用重试,这将禁用透明重试和任何配置的重试策略。
透明重试
故障可能发生在不同的阶段。即使没有明确的重试策略,gRPC 也可能会执行透明重试。这些重试的程度取决于故障发生的时间
- 当 RPC 从未离开客户端时,gRPC 可能会执行无限透明重试。
- 当 RPC 到达 gRPC 服务器库,但从未被服务器应用程序逻辑看到时,gRPC 执行单次透明重试。请注意这种类型的重试,因为它会增加网络的负载。
您可以通过专注于 gRPC 支持的关键步骤和配置来优化应用程序的重试功能。
- 最大重试尝试次数
- 指数退避
- 可重试状态代码集
重试可以通过 gRPC 服务配置 进行配置,粒度为每个方法。配置包含以下旋钮
"retryPolicy": {
"maxAttempts": 4,
"initialBackoff": "0.1s",
"maxBackoff": "1s",
"backoffMultiplier": 2,
"retryableStatusCodes": [
"UNAVAILABLE"
]
}
正负 20% 的抖动会应用于退避延迟,以避免大量客户端同时对服务器造成冲击。在上面的示例配置中,initialBackoff
设置为 100 毫秒,因此第一次尝试后的实际退避延迟将是 [80 毫秒,120 毫秒]
范围内的随机时间段。
gRPC 支持节流限制,可防止服务器因重试而过载。以下是重试节流配置的示例
"retryThrottling": {
"maxTokens": 10,
"tokenRatio": 0.1
}
对于每个服务器,gRPC 客户端跟踪一个 token_count
(最初设置为 maxTokens
)。失败的 RPC 将计数减 1,成功的 RPC 将计数增加 tokenRatio
。如果 token_count
低于 maxTokens
的一半,则会暂停重试,直到计数恢复。
此外,对冲是重试的补充功能,可以类似地进行配置。有关更多详细信息,请参阅对冲指南。
重试可观察性
当启用重试功能时,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
在 Otel 指标的 gRFC, 重试状态的 gRFC 中查找深入的指标和跟踪信息,以及配置说明。
语言指南和示例
语言 | 示例 | 文档 |
---|---|---|
C++ | ||
Go | Go 示例 | |
Java | Java 示例 | Java 文档 |
Python | Python 示例 |