已采纳
回答正文
回复
讨论正文
该问题的正文、回答与讨论。
背景
做一个订单详情页聚合接口(Java/Spring Boot + HikariCP 5.1 + MySQL 8.0),一次业务请求要串行/并行发 5~7 条 DB 查询(订单主表、明细、库存、价格、风控、物流),下游还有 2 个 RPC(Redis 命中率高、一个内部 gRPC 服务)。上游网关给的端到端超时是 800ms(P99 SLO)。
社区里超时预算切分讲得比较透的两篇我都读过:林砚舟《超时与重试》(id=23) 给了"预算按层切"的原则,id=1377 那个提问把重试放大系数算得很细。但这两篇都默认一层 = 一次下游调用,而我这里的坑是:一层 = 一个逻辑业务请求,但落到 DB 上是 N 条查询——这个"一层内多查询"的预算怎么切,我没找到正面讨论。
现象
max_execution_time=200),结果:
max_execution_time 是 per-statement 的,5 条查询各 200ms 上限 = 1s 总预算,直接超过上游 800ms 网关超时,上游先超时关连接,下游还在跑,连接池被占住(HikariCP 连接持有时间被拉长)。已尝试的排查与结果
max_execution_time 统一 200ms:如上,总预算超网关,错误率反升。Connection is not available(和 id=18、id=214 描述的现象一致)。Semaphore 做背压 + 每查询 150ms 超时 + 5 条并行:错误率回到 0.3%,但 P999 出现一批 750ms 的"4 条成功 1 条超时"的降级长尾,业务侧要处理部分成功语义,成本很高。期望得到的答案形态
希望社区能给出一个可复用的预算分配模型,而不是具体某个值。具体想问:
max_execution_time 这种 DB 层硬超时,和业务层"总预算耗尽即放弃"的软超时,到底谁该是主、谁该是兜底? 我现在的直觉是"业务层软超时为主、DB 层硬超时是保险丝(设大一点比如 3s)",但不确定。我倾向的立场(欢迎反驳):超时预算是容量规划的一部分,不是配置项——所以应该从"业务可接受的最差响应时间"倒推,而不是从"单查询 P99"正推。但这个倒推公式我没见过有人写得完整,想看看社区有没有更系统的做法。