gRPC -- Guides -- Request Hedging

请求对冲机制

说明什么是请求对冲以及如何进行配置

概述

对冲是 gRPC 支持的两种可配置重试策略之一。启用对冲后,gRPC 客户端会向不同后端发送多份相同请求 ,并使用最先收到的响应。客户端随后会取消所有未完成的请求,并将响应传递给应用层。

基础对冲流程

  1. 客户端应用发起 gRPC 调用
  2. gRPC 客户端库向多个后端发送 RPC
  3. 响应最快的后端返回成功结果
  4. 客户端接收响应并向其他后端发送取消指令
  5. 将响应与状态码返回给应用层

使用场景

对冲是一种用于降低大规模分布式系统长尾延迟 的技术。虽然简单实现可能会大幅增加后端服务器负载,但可以在仅小幅增加负载的前提下,获得大部分延迟降低效果。

关于长尾延迟的深入讨论,可参考 Jeff Dean 与 Luiz André Barroso 的经典文章《The Tail At Scale》。

在 gRPC 中配置对冲机制

对冲可通过 gRPC 服务配置方法粒度进行配置,配置包含以下参数:

复制代码
"hedgingPolicy": {
  "maxAttempts": 整数,
  "hedgingDelay": JSON proto3 Duration 类型,
  "nonFatalStatusCodes": gRPC 状态码数组(整数或字符串)
}
  • maxAttempts :等待成功响应时,最大并发请求数。必填项,必须指定;若大于 5,gRPC 会按 5 处理。
  • hedgingDelay :等待成功响应期间,客户端发送下一个请求前的等待时间。可选项,未指定则所有 maxAttempts 个请求会同时发送
  • nonFatalStatusCodes :可选项,gRPC 状态码列表。若某个对冲请求失败的状态码不在此列表中,客户端会取消所有未完成请求并将响应返回应用。

对冲策略

当应用发起包含 hedgingPolicy 配置的 RPC 调用时:

  1. 原始 RPC 会立即发送,与普通非对冲调用一致。
  2. 经过 hedgingDelay 仍未收到成功响应,则发送第二个 RPC。
  3. 再经过 hedgingDelay 仍无响应,则发送第三个 RPC,依此类推,直至达到 maxAttempts
  4. gRPC 调用的超时时间作用于整个对冲请求链;超时后无论是否有请求在执行,均判定失败。

收到成功响应时:

  • 取消所有未完成的对冲请求,将响应返回客户端应用层。

收到非致命状态码错误时:

  • 立即发送下一个对冲请求,跳过剩余 hedgingDelay

收到其他状态码时:

  • 取消所有未完成 RPC,将错误返回应用层。

若所有对冲请求均失败:

  • 不再额外重试。对冲本质可理解为在收到失败前就提前发起重试

若收到服务端回退(禁止重试):

  • 本次调用不再发送后续对冲请求。

对冲 RPC 的限流

gRPC 提供对冲 RPC 限流机制,防止服务端过载。限流同样通过服务配置的 RetryThrottlingPolicy 配置:

复制代码
"retryThrottling": {
  "maxTokens": 10,
  "tokenRatio": 0.1
}
  • 客户端为每个服务名维护一个 token_count,初始值为 maxTokens
  • 每次 RPC 失败:token_count 减 1。
  • 每次 RPC 成功:token_count 增加 tokenRatio

对冲限流规则:

  • 第一个请求始终发送。
  • 后续对冲请求仅当 token_count > maxTokens / 2 时才发送
  • token_count 小于等于阈值,后续对冲请求直接取消;若无已发送的对冲 RPC,则将失败返回应用。

非致命状态码服务端回退禁止重试的失败,会计入限流统计,避免将非法参数等客户端错误与服务端故障混淆。

服务端回退机制

服务端可通过在响应元数据中显式设置回退指令:

  • 回退指令为禁止重试:不再发送后续对冲请求。
  • 回退指令为指定延迟后重试:等待指定时间后再发送下一个对冲请求。

服务端回退使用元数据键:grpc-retry-pushback-ms

  • 值为 ASCII 编码的 32 位有符号整数,表示等待毫秒数。
  • 值为负数或无法解析:视为服务端要求完全禁止重试

参考资源

语言支持

Language Example
Java Java example
C++ Not yet available
Go Not yet supported
相关推荐
千里马-horse1 天前
gRPC -- Java 基础教程
java·开发语言·grpc
只做人间不老仙3 天前
C++ grpc 元数据示例学习
后端·grpc
切糕师学AI4 天前
gRPC 负载均衡详解:从原理到最佳实践
架构·负载均衡·grpc
切糕师学AI6 天前
深入解析 gRPC:高性能开源 RPC 框架的原理与实战
网络协议·rpc·开源·grpc
wuchen10047 天前
使用Postman测试grpc接口
postman·grpc
YF021112 天前
Protobuf与 gRPC 的关系:从理论到 Android + Go 实战通信全解析
android·后端·grpc
猫吻鱼13 天前
【笔记03】【Grpc 和 Protobuf】
grpc·protobuf
只做人间不老仙16 天前
C++ grpc 截止时间示例学习
后端·grpc
ironinfo22 天前
.net 高并发服务性能瓶颈排查处理
性能优化·.net·grpc