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 -- Guides -- Reflection
grpc·反射
ALex_zry18 天前
gRPC服务熔断与限流设计
c++·安全·grpc
人间打气筒(Ada)23 天前
「码动四季·开源同行」go实战案例:如何在微服务中集成 Zipkin 组件?
微服务·golang·开源·grpc·zipkin·http调用
只做人间不老仙1 个月前
grpc测试工具ghz的使用
后端·grpc
只做人间不老仙1 个月前
C++ grpc rpc取消示例学习
后端·grpc
stark张宇2 个月前
微服务架构必备:Gin + gRPC + Consul + Nacos + GORM 打造用户服务
微服务·gin·grpc
雮尘2 个月前
手把手带你玩转Android gRPC:一篇搞定原理、配置与客户端开发
android·前端·grpc
REDcker3 个月前
gRPC开发者快速入门
服务器·c++·后端·grpc
REDcker3 个月前
gRPC完整文档
服务器·网络·c++·网络协议·grpc