超时预算别层层加码:把剩余时间传给下游

举报
yd_216508571 发表于 2026/10/31 01:18:55 2026/10/31
【摘要】 超时预算别层层加码:把剩余时间传给下游网关给一次请求留了 800 毫秒。订单服务自己又设了 800 毫秒,库存服务再设 800 毫秒。用户侧早就超时断开,下游还在空转,重试再叠一层,就把依赖打成重试风暴。超时不是每一跳都重新发一张整额支票,而是一张会变少的预算。 先约定三件事入口只发一次总预算,例如 800ms,并写进上下文,而不是只写在网关配置里。每一跳取 min(自己的上限, 剩余预算...

超时预算别层层加码:把剩余时间传给下游

网关给一次请求留了 800 毫秒。订单服务自己又设了 800 毫秒,库存服务再设 800 毫秒。用户侧早就超时断开,下游还在空转,重试再叠一层,就把依赖打成重试风暴。

超时不是每一跳都重新发一张整额支票,而是一张会变少的预算。

先约定三件事

  1. 入口只发一次总预算,例如 800ms,并写进上下文,而不是只写在网关配置里。
  2. 每一跳取 min(自己的上限, 剩余预算 - 预留)。预留留给序列化、队列等待和返回路径,常见是 20 到 50ms。
  3. 剩余预算小于预留时直接失败,不要再打下游。失败要带原因,方便入口决定是否对用户重试。

一个数字例子

入口预算 800ms。网关已用 30ms,剩余 770ms。订单服务上限 500ms,预留 40ms,实际截止时间是 now + min(500, 770-40) = 500ms。库存服务收到时剩余 180ms,自身上限 300ms,预留 40ms,于是只用 140ms。若剩余只剩 15ms,库存服务不再发起调用,返回 BUDGET_EXHAUSTED。

这样做的好处是:下游的慢调用不会超过用户还能等待的时间;入口的重试只会打在“还来得及”的请求上。

和熔断、限流怎么配合

  • 熔断看的是错误率,不替代预算。预算耗尽应记为取消,不要记成下游 5xx,否则熔断会被自己的超时放大。
  • 限流保护容量,预算保护时延。两者都要有,但计数口径分开。
  • 重试只允许在剩余预算足够覆盖一次完整下游调用时发生,并且要换一个幂等键或沿用同一个,避免重复下单。

落地时容易踩的坑

  • 只在日志里打印超时,没有把截止时间传给客户端。线程池里的任务拿不到父请求的剩余时间,预算就断了。
  • 用固定 sleep 做退避,不看剩余预算。第二次重试发出去时,用户连接已经关了。
  • 把时钟差当成预算。跨机器用单调时钟算本机耗时,截止时间用绝对时间并允许少量时钟偏移。

把“每一层都设一个看起来安全的大超时”改成“把剩余时间传下去”,慢依赖会在预算用完时自己停下来,而不是靠用户刷新把流量再放大一轮。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。