JDBC 数据库连接池
JDBC 数据库连接池
数据库连接池是管理 Connection 的容器。应用从池中借用连接,用完后归还;连接池负责复用、上限、等待超时、空闲回收和健康检查。
为什么不能每次新建连接
创建物理连接涉及 TCP 建连、认证和会话初始化,成本远高于一次普通 SQL。无边界地创建连接还会耗尽数据库可用连接数。
连接池带来的主要收益:
- 复用连接,降低请求延迟。
- 用最大池大小保护数据库。
- 用获取超时避免线程无限等待。
- 回收长期空闲或失效连接。
- 借助监控暴露活跃数、空闲数和等待时间。
DataSource 标准接口
JDBC 使用 javax.sql.DataSource 作为标准入口:
代码块收起展开
try (Connection connection = dataSource.getConnection()) {
// 执行 SQL
}常见实现包括 HikariCP、Druid、DBCP、C3P0。Spring Boot 默认通常使用 HikariCP;Druid 提供额外监控与扩展。产品选择应基于稳定性、性能、观测需求和团队维护成本。
Spring Boot 配置示例
代码块收起展开
spring:
datasource:
url: jdbc:mysql://localhost:3306/web
username: ${DB_USER}
password: ${DB_PASSWORD}
hikari:
maximum-pool-size: 10
minimum-idle: 2
connection-timeout: 3000
idle-timeout: 600000池大小不是越大越好。数据库 CPU、磁盘能力、事务时长和并发模型共同决定合理值;应结合连接等待时间、数据库负载和压测结果调整。
close 的真实语义
从连接池取得的通常是代理连接。业务调用 close() 后,代理清理会话状态并把底层连接归还池中。忘记关闭仍会造成连接泄漏,最终让所有请求阻塞在获取连接上。
生产排查
| 现象 | 优先检查 |
|---|---|
| 获取连接超时 | 活跃连接数、慢 SQL、长事务、连接泄漏 |
| 数据库连接数过高 | 多实例总池大小、连接未归还 |
| 空闲连接失效 | 数据库超时、网络设备超时、保活设置 |
| 请求延迟抖动 | 获取连接等待、连接创建、SQL 耗时 |
连接池解决的是连接生命周期与容量管理,不会自动修复慢 SQL、错误事务边界或 N+1 查询。