超时要分层预算
一次请求会穿过数据库、应用、反向代理、网关、客户端多层,每层都有自己的超时值。合理做法是让内层超时小于外层:内层先超时并快速失败,外层才来得及决定重试还是返回错误。反过来的配置(外层 30 秒、内层 60 秒)会造成外层已经断开、内层还在跑,请求堆积、重复执行,最终演变成级联失败。
基本信息
| 核心原则 | 内层超时 < 外层超时,失败在最内层尽早暴露 |
|---|---|
| 典型分层 | 数据库 5-10s → 应用调用下游 10s → 代理/网关 30s → 客户端 60-120s |
| 必须区分 | 连接超时、读超时、总超时三类,日志要能分别记录 |
| 重试前提 | 仅对幂等接口重试,配退避与熔断,避免放大流量 |
| 设定依据 | 按依赖的 P99 延迟与业务可接受等待时间确定,不凭感觉 |
典型使用场景
- 新接入一个下游服务:为它单独设定连接与读取超时,避免用全局默认值
- 排查雪崩:核对各层超时是否内外层颠倒,找出请求堆积的根源
- 高延迟链路(跨地域)上频繁误失败:确认超时值是否按实际 P99 设定
- 批量接口设计:为单条与整体分别设定超时,避免一条慢数据拖垮整批
- 网关侧保护:让代理超时略大于应用超时,把错误控制权留在应用内部
典型配置参考
典型配置参考
# 数据库连接/查询:5-10s(按业务可接受等待调整)
# 应用 HTTP 客户端:连接 2s / 读取 10s,分别设置不共用
# nginx → 上游:
proxy_connect_timeout 3s; # 与后端建立连接的超时
proxy_send_timeout 10s; # 向后端发送请求的超时
proxy_read_timeout 30s; # 等待后端响应的超时
# LB 或网关:空闲与请求超时 ≥ 应用侧超时(如 60s),避免网关先断
# 客户端:总超时 60-120s,并区分可重试与不可重试的错误类型分层配置对照
| 层 | 关注点 | 错配后果 |
|---|---|---|
| 数据库/缓存 | 连接超时应短,读超时按查询复杂度设定 | 读超时过长会长时间占住连接池 |
| 应用调用下游 | 连接与读分开设定,按下游实际 P99 | 与数据库超时颠倒会先耗尽连接池 |
| 反向代理 | read_timeout 覆盖后端最慢正常响应 | 设置过短会在正常慢查询上大量 502 |
| 网关/LB | 应大于应用超时,留出错误处理时间 | 小于内层会导致错误信息丢失、难以定位 |
| 客户端 | 总超时 + 友好提示,避免无限等待 | 无限等待会造成用户重复提交与重复执行 |
超时不是越短越好:设得过短会在跨地域等高延迟链路上造成大面积误判失败;应基于实测 P99 与业务容忍度设定,并在变更后观察错误率变化。