数据库连接池
解释为什么后端服务需要连接池,以及连接复用、并发上限、超时和容量配置的核心权衡。
#type / concept
#status / growing
#tech / dev / backend
#resource / database
[!info] related notes
- 所属 MOC: Node.js 后端面试 MOC, 数据库 MOC
- 前置概念: MySQL, PostgreSQL
- 并列概念: 对象关系映射 ORM
数据库连接池
一句话定义
数据库连接池是服务端用来复用数据库连接、限制并发连接数并平衡吞吐与数据库压力的基础设施。
核心机制 / 工作原理
如果每个请求都自己新建数据库连接,代价会很高:
- 建连有开销
- 握手有开销
- 数据库能承受的连接数有限
所以后端通常会:
- 预先建立一批连接
- 请求到来时从池里借连接
- 用完后归还
- 池自己控制最大连接数、超时和空闲回收
连接池最常见的配置项
max/connectionLimit:最多允许多少连接idleTimeout:空闲连接多久回收acquireTimeout:借连接最多等多久min:是否保留最小空闲连接
这些配置的本质不是“越大越保险”,而是要在:
- 请求峰值
- 查询耗时
- 数据库承载能力
之间做平衡。
最小例子 / 最小场景
错误心智:
每个 HTTP 请求都自己
createConnection()
更稳的做法:
服务启动时创建连接池,请求阶段只做
query或getConnection/release
一个典型事务模式通常长这样:
const conn = await pool.getConnection();
try {
await conn.beginTransaction();
await conn.query(...);
await conn.query(...);
await conn.commit();
} catch (error) {
await conn.rollback();
throw error;
} finally {
conn.release();
}
边界与易混淆点
连接池不是越大越好
池太大只会把压力更快打到数据库上。
真正要看的不是“应用层能开多少连接”,而是:
- 数据库实例上限
- 平均查询耗时
- 峰值并发
- 是否还有别的服务也在共享同一个数据库
连接池耗尽会表现成什么
常见现象有:
- 请求排队变长
- 获取连接超时
- API RT 抖高
- 应用 CPU 可能不高,但接口已经明显变慢
所以排查慢接口时,不能只看 SQL 本身,也要看是不是“根本拿不到连接”。
事务里要特别注意释放
事务代码通常是:
- 获取连接
- 开事务
- 提交或回滚
- 最后 release
如果异常路径没释放,连接池就会被慢慢耗尽。
最小面试回答模板
如果面试官问“为什么后端要用连接池”,一个稳的回答是:
因为数据库连接建立成本高,而且数据库能承受的并发连接数有限。连接池的作用是复用连接、限制并发、控制等待时间。真正要关注的不只是能不能连上,而是池大小、获取超时、事务释放和数据库整体容量,否则高峰期很容易出现池耗尽,导致接口整体变慢。