标准答案

  1. 入口生成 deadline,下游读取剩余时间并把它传给数据库、RPC、HTTP 和消息操作。
  2. 局部超时应小于剩余预算,预留序列化、响应和日志时间;不能每层都重新从零开始计时。
  3. 截止时间到达后停止新工作、取消可取消调用并释放连接,记录是哪个层耗尽预算。
  4. 重试要消耗同一预算,剩余时间不足时应快速失败或转异步处理。

题目解析

局部超时是某一层的保护,deadline 是整个请求的剩余预算。每层都从零开始设置 5 秒,最坏情况下会把调用链串成多倍等待,导致入口已经超时而后台仍占用资源。

传播 deadline 时要扣除本层序列化、清理和响应时间,并把剩余预算传给数据库、RPC 和 HTTP。重试必须消耗同一预算,不能因为换了一次尝试就重新获得完整时间。

截止时间到达后要停止新工作、取消可取消调用和归还连接。对于不可取消的副作用,应该记录结果未知并通过幂等或状态查询收敛,而不是假设调用已经停止。

常见误区

  • 误区:每层都设置 5 秒。改正:使用绝对 deadline 和剩余时间,保证端到端预算不会层层相加。
  • 误区:重试时重置超时。改正:所有重试共享原始截止时间,剩余时间不足就快速失败或转异步。
  • 误区:下游超时后不取消上游等待。改正:传播取消并释放连接,无法取消时记录任务状态,避免后台继续无界执行。

作者信息