← 中文资源

简体中文版本

Go 中 gRPC 的 DeadlineExceeded 在服务间级联

通过传播 context 截止时间并缩短下游超时,诊断级联的 gRPC DeadlineExceeded。

阅读英文原文

症状

调用以 DeadlineExceeded 失败,且负载下单个慢依赖会让多个服务同时超时。截止时间是一份共享预算:若每一跳都用自己的宽松超时,慢尾会吃掉总量,最初调用方只好放弃。当处理器使用 context.Background 而非传入的 context 时,截止时间未被传播,每一跳都无界运行。

诊断

用 grpcurl 单独调用定位某跳;检查处理器的 context 传播;为每一跳从剩余预算派生更短的超时。

grpcurl -d '{}' -connect-timeout 5 host:port service/Method

根因

端到端请求超出其截止时间,因为时间消耗在多个跳上却没有共享预算,常常由于截止时间未传播、慢依赖吃掉了额度。

修复

把请求 context 传向每个下游调用,让取消与截止时间随流而下;按剩余预算为每跳派生更短超时,使总延迟落在调用方上限内。避免超出剩余截止时间的重试,因为无法完成的重试只会增加延迟。

验证

在代表性负载下走完整路径确认不再出现 DeadlineExceeded,并确认此前慢的依赖已被其跳级截止时间约束。端到端满足预算即证明修复。

常见陷阱

为每一跳设置相同的大超时会让最慢的一跳拖垮整体;应按预算递减分配。