连接池大小应≤max_connections×0.7,如rds为1000则总池大小≤600;thread_pool_size建议设为cpu核心数,上限不超过其2倍,8核机器推荐起始值为8。

连接池大小设多少,得先看 MySQL 的 max_connections
应用侧连接池最大值(如 HikariCP 的 maximumPoolSize)不能突破数据库端的硬限制。执行 SHOW VARIABLES LIKE 'max_connections'; 查当前值,常见默认是 150 或 1000(云数据库如 RDS 基础版常为 1000)。若你有 4 台应用实例,每台池子设 30,理论峰值就是 120,已接近本地 MySQL 默认 150 的上限——但别忘了 DBA 维护、备份、监控脚本也会占连接,必须留出至少 20% 余量。
更稳妥的做法是:连接池总容量 ≤ max_connections × 0.7。比如 RDS 返回 max_connections=1000,那所有应用实例加起来的 maximumPoolSize 总和建议 ≤ 600。
- 查实时连接压力:
SHOW STATUS LIKE 'Threads_connected';,持续观察 15 分钟以上峰值,比静态配置更有说服力 - 如果该值长期 > 90% 的
max_connections,优先排查连接泄漏(未 close()、未归还),而不是直接调大池子 - 云环境尤其注意:阿里云 PolarDB、腾讯云 CynosDB 等对单连接内存开销更敏感,盲目设高反而触发主动 Kill
thread_pool_size 超过 CPU 核心数 × 2 就容易抖动
启用线程池插件后,thread_pool_size 不是越大越好。它本质是“工作线程分组数”,每组独立调度,目的是减少传统 one-thread-per-connection 模式下的上下文切换开销。但设得过大,会导致内核频繁在多个线程组间切换,反而增加延迟抖动。
实操建议:从 CPU 核心数 开始试,上限不要超过 CPU 核心数 × 2。例如 8 核机器,thread_pool_size = 8 是较稳起点;若观察到 SHOW STATUS LIKE 'Thread_pool_waited'; 持续非零,再逐步加到 12,但跳过 16。
- 必须配套检查:
Thread_pool_idle_threads是否长期过低(Thread_pool_waited 上升则意味着请求排队,不是线程不够,可能是 SQL 慢或锁争用 - 线程池只对 InnoDB 引擎有效,MyISAM 场景下无效
- 插件加载命令是:
INSTALL PLUGIN thread_pool SONAME 'thread_pool.so';,部分云数据库(如早期 RDS 版本)不支持该插件,需确认文档
应用连接池参数不能只看 maxActive,minIdle 和验证逻辑更关键
很多人把 maxActive(或 HikariCP 的 maximumPoolSize)当成唯一调优目标,结果池子堆得高,空闲连接却大量失效、被防火墙静默断开,最终引发“获取连接超时”。
真正影响稳定性的三个联动参数是:minIdle、testWhileIdle、validationQuery。它们共同决定:空闲连接是否可靠、能否及时剔除僵尸连接。
-
minIdle建议设为maximumPoolSize的 1/3~1/2(如池子上限 30,则minIdle=10~15),避免突发流量来临时全量创建新连接 - 必须开启
testWhileIdle=true,并配timeBetweenEvictionRunsMillis=30000(30 秒检测一次),否则空闲 8 小时的连接大概率已被中间网络设备断开 -
validationQuery只能用SELECT 1,不能用SELECT NOW()或带函数的语句——MySQL Connector/J 8.0+ 驱动会拒绝执行 - connectionTimeout 别设成 30 秒,2~5 秒更合理;超时太久会让整个 HTTP 接口卡住,掩盖真实问题
并发能力瓶颈往往不在连接数,而在 wait_timeout 和连接复用方式
很多“Too many connections”错误,根源不是池子小,而是应用没正确复用连接,或者数据库端空闲连接回收太慢,导致大量半死连接堆积。
wait_timeout 和 interactive_timeout 默认 28800 秒(8 小时),而应用连接池的空闲回收周期通常只有几分钟。这会造成:连接池以为连接还活着,MySQL 却早已关闭它,下次取出来就报错 “Connection closed by remote host”。
- 建议将这两个参数同步调低至 300~600 秒(5~10 分钟),与连接池的
idleTimeout(如 HikariCP 默认 600000ms)对齐 - 检查应用代码:是否每个 DAO 方法都确保
try-with-resources或显式close()?有没有在 Stream 或 CompletableFuture 中漏掉连接释放? - 短连接场景(如 CLI 工具、批处理脚本)要单独评估,这类客户端不走连接池,
max_connections需按N × max_worker+ 100 预留,不能套用长连接公式
Threads_connected 实时值、以及 Thread_pool_waited 这类底层指标——三者脱节,调参就是蒙眼走路。











