← 中文资源

简体中文版本

在服务链中传播 gRPC 截止时间

为每次 gRPC 调用设置截止时间,把剩余时间转发给下游,并返回 DEADLINE_EXCEEDED 而非永久等待。

阅读英文原文

概述

每条 RPC 都必须有截止时间:一次没有截止时间的调用可能无限期占用线程。传播剩余预算并践行取消,可使慢依赖只拖累单个请求而非整池。

关键步骤

  1. 对每次出站调用按配置设置明确的截止时间。
  2. 读取入站截止时间,从剩余时间推导每个下游截止时间。
  3. 上下文结束时立即返回 DEADLINE_EXCEEDED。
  4. 截止时间过后用上下文取消在途工作。

验证

  • 每次出站 RPC 都有明确截止时间。
  • 下游截止时间短于上游。
  • 超时调用返回 DEADLINE_EXCEEDED。
  • 取消能停止处理函数中的阻塞工作。

注意事项

  • 对不配合的代码,截止时间不等于取消;无视上下文的阻塞调用仍会挂起。
  • 若未依据真实延迟数据设定过激的截止时间,会抬高错误率。

适用范围

本条目围绕「在服务链中传播 gRPC 截止时间」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。

ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
defer cancel()
resp, err := client.Get(ctx, req)
if status.Code(err) == codes.DeadlineExceeded {
	return nil, err
}