不是。盲目调高最大连接数会压垮数据库或触发连接拒绝,受限于数据库连接上限、资源消耗及真实瓶颈;合理值多为20~50,需压测验证,并设置idleTimeout≤wait_timeout(如5分钟)避免失效连接。

连接池最大连接数设得越高越好?
不是。盲目调高 maxPoolSize(如 HikariCP 的 maximumPoolSize,Druid 的 maxActive)反而会压垮数据库或触发连接拒绝。
- 数据库本身有最大连接数限制(如 MySQL 默认
max_connections=151),超过后新连接直接报错Too many connections - 每个连接占用内存和线程资源,应用端线程数激增可能引发 GC 频繁甚至 OOM
- 真实吞吐量不取决于连接数上限,而受限于数据库 CPU、IO、锁竞争等瓶颈;实测中多数业务
maxPoolSize=20~50已足够 - 建议用压测工具(如 JMeter)配合数据库
SHOW PROCESSLIST观察活跃连接分布,再反推合理值
空闲连接回收配置被忽略
idleTimeout(HikariCP)、minEvictableIdleTimeMillis(Druid)这类参数常被设为 0 或极大值,导致连接长期空闲却未释放,最终占满数据库连接池。
- MySQL 默认 wait_timeout=28800 秒(8 小时),若应用端
idleTimeout> 这个值,连接在 DB 侧已被服务端关闭,但应用仍认为有效,下次使用就抛Connection reset或Communications link failure - 推荐设置:HikariCP 中
idleTimeout设为 300000(5 分钟),且必须 wait_timeout;同时开启connection-test-query或validationQuery做借用前校验 - 注意 Druid 的
testWhileIdle=true需搭配timeBetweenEvictionRunsMillis才生效,单独设前者无效
连接泄漏没配监控就上线
连接未 close、异常路径漏掉 connection.close()、或用了 try-with-resources 但底层 DataSource 不支持自动归还,都会造成连接持续累积——这是最隐蔽也最致命的问题。
- HikariCP 可通过
leakDetectionThreshold(毫秒)主动检测,例如设为 60000,超 60 秒未归还就打印堆栈;但该参数默认关闭,上线前必须显式启用 - Druid 提供
removeAbandonedOnBorrow=true+removeAbandonedTimeout=1800,但会牺牲部分性能,且仅适用于旧版(1.2.16+ 推荐用removeAbandonedOnMaintenance) - 更可靠的方式是结合 APM(如 SkyWalking)追踪 connection 获取/归还链路,或定期查 HikariCP 的
HikariPoolMXBean.getActiveConnections()指标
事务传播与连接绑定关系被误读
很多人以为 Spring 的 @Transactional 会自动复用连接,其实它依赖的是 DataSource 绑定的 ThreadLocal,一旦跨线程(如 CompletableFuture、线程池回调)、或手动 new Connection,连接就断开了。
- Spring 默认使用
DataSourceTransactionManager,其事务上下文与当前线程强绑定;异步操作需显式传播,例如TransactionSynchronizationManager.getCurrentTransactionName()+ 手动传递 connection - MyBatis 的
SqlSession默认非线程安全,多线程共用一个SqlSession实例会导致连接错乱,应确保每个线程独占 session - 连接池返回的 connection 是包装类(如 HikariProxyConnection),重写了
close()方法——它不真正关闭,而是归还到池中;直接调connection.unwrap()拿原生 connection 后又没处理好,极易泄漏










