已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
背景 订单服务,Spring Boot 3.2 + JDK 17 + HikariCP 5.1.0 + MySQL 8.0,K8s 1.28 滚动发布(maxUnavailable=1、terminationGracePeriodSeconds=60,preStop sleep 10s 等摘流)。有 2~3 条报表类 SQL 正常耗时 3~8s,偶发慢到 20s+。最近一次发布,摘流后仍有 2 个请求带着慢 SQL 跑到 Pod 进入 Terminating,用户侧看到 502。
现象
close() 被调用;close() 之后到进程退出之间,最长一次等了 40s+(期间 active=1,那个慢 SQL 还没跑完),最后进程是被 SIGKILL 强杀的(grace 60s 用尽),对应 502;close() 只等了 3s 就退出,同一批流量没 502——差别只在当时有没有 in-flight 慢 SQL。已尝试与结果
socketTimeout / queryTimeout 调小(8s):能兜住极端慢 SQL,但报表类合法长查询被误杀,业务不接受;close() 内部是 closeFuture + 等待 active 连接归还,没有看到对 in-flight 语句执行 statement.cancel() 的调用,即它只是阻塞等待,不主动打断慢 SQL。这一点如果不对请纠正我。期望得到的答案形态
close() 的准确语义——是「中断 in-flight 查询」还是「阻塞等待归还直到进程被杀」?有没有官方或源码级的说法?terminationGracePeriodSeconds 该按「P99 查询时长 + 摘流时间 + 余量」来定,还是有更稳的机制(比如 shutdown 时主动 cancel、或把长查询拆到独立服务)?wait_timeout / 连接清理需要额外处理吗?