大家好,我是十三!欢迎来到十三Tech。
去年有个项目在凌晨报障——业务系统大量报 "Communications link failure",看监控发现是 MySQL 服务端主动断开了连接。排查了一晚才搞明白:开发在配置文件里改了 wait_timeout=28800(8 小时),但凌晨流量低、连接空闲了 8 小时被 MySQL 干掉,应用侧的连接池还以为连接是好的,下次取出来用就崩了。
更坑的是——wait_timeout 有个孪生兄弟叫 interactive_timeout,99% 的配置只改了一个。两个参数行为略有差异,只改一个意味着交互式和长连接的空闲超时不一致,会引发玄学的连接断开问题。
这一篇就聊聊连接器在做什么、两个 timeout 的差别,以及连接池配置最容易踩的坑。
一、连接器在解决什么——不是"建立 TCP"
教科书定义:连接器负责跟客户端建立 TCP 连接、做权限校验、维持连接。这话没错但太浅。连接器真正管的是"连接的生命周期"——建立、维持、空闲回收、断开。
连接器的工作分四步:
- 建立 TCP 三次握手——这是网络层的事,连接器只是触发
- 权限校验——查 mysql.user 表里的密码、host、privs
- 维持连接——管理这个连接的用户上下文、事务状态、临时表
- 空闲超时回收——这是出问题最多的环节
判断口诀:连接能建立但被神秘断开 → 看 timeout;连接根本建立不了 → 看权限或 max_connections。
连接器跟后面几节流水线的关系——连接建立后,这个连接的所有 SQL 都共用同一个连接上下文(用户、当前库、事务、变量)。所以连接是一个"会话",它的状态会持续到断开。
二、wait_timeout vs interactive_timeout 的真相
这是连接器最容易被忽略的一对参数。两个参数都管"空闲连接多久断开",但作用范围不同:
interactive_timeout:交互式连接(用 mysql 客户端那种)的空闲超时wait_timeout:非交互式连接(JDBC、Go database/sql 这种)的空闲超时
判断"交互式还是非交互式"靠的是连接建立时客户端传的 CLIENT_INTERACTIVE 标志位——99% 的应用客户端(包括 JDBC、Go driver、Python driver)都不传这个标志,所以应用连接的空闲超时由 wait_timeout 决定。
但坑在这里:MySQL 启动时 wait_timeout 的值会从 interactive_timeout 拷一份——也就是说如果你只改 interactive_timeout,wait_timeout 也跟着变了;但如果两个都改不一致,wait_timeout 用自己的值。
SHOW VARIABLES LIKE '%timeout%';
99% 的运维文档教大家"改 wait_timeout",但漏了同步改 interactive_timeout——结果 DBA 用 mysql 客户端连上没事(用 interactive_timeout),应用挂(用 wait_timeout),debug 半天。
正确做法:两个都设成一样的值,并且远大于你连接池的 maxIdleTime——让连接池主动回收空闲连接,而不是让 MySQL 被动断开。
三、连接池配置的三个常见坑
讲完 timeout,再说三个连接池最容易踩的坑——JDBC、HikariCP、Go database/sql 全都涉及。
坑一:连接池 maxIdleTime > MySQL wait_timeout。这是最经典的"凌晨报障"——连接池以为连接还在,MySQL 早断了。正确做法:maxIdleTime 设成 wait_timeout 的 1/3 到 1/2,主动回收。
坑二:不做连接心跳。空闲连接不主动 ping,等用的时候才发现已经断了——典型的"取出来就崩"。正确做法:开启连接池的 keepalive 或 testOnBorrow,HikariCP 默认会发 ping。
坑三:max_connections 设太小。MySQL 的 max_connections 默认 151,业务稍微一扩容就 "Too many connections"。正确做法:根据 (内存 - 系统占用) / 单连接内存 估算上限,典型值 500-2000,同时把 thread_cache_size 调到 100+,避免频繁创建线程。
回头看那个凌晨报障——根因是 wait_timeout=28800 比连接池 maxIdleTime=30000(约 8.3 小时)短,连接被 MySQL 抢先断开。修复方法很简单:把 wait_timeout 改到 12 小时、连接池 maxIdleTime 改到 4 小时,问题彻底消失。
连接器真正教会我的,不是"建立 TCP 连接",而是连接是"会话",会话有生命周期——建立只是开始,维持和回收才是真正容易出问题的地方。
下一篇讲分析器、优化器、执行器——这三个组件决定了 SQL 怎么变成执行计划。
关于十三Tech 资深服务端研发,AI 实践者,专注分享真实可落地的技术经验。 相信 AI 是程序员的最佳搭档。
联系方式:569893882@qq.com GitHub:@TriTechAI
