连接池
一、概述
1.1 什么是连接池
连接池(Connection Pool)是:
预先创建一定数量的连接,并统一管理和复用这些连接,而不是每次请求都重新建立连接。
这里的"连接"不仅指数据库连接,还包括:
- MySQL 连接
- Redis 连接
- HTTP 连接
- gRPC 连接
- Kafka 连接
- RabbitMQ 连接
本质上,只要是建立成本较高、可以复用的连接,都适合使用连接池。
1.2 为什么需要连接池
假设没有连接池:
每个请求执行流程如下:
HTTP Request
│
▼
创建 MySQL 连接
│
▼
执行 SQL
│
▼
关闭连接
如果系统每秒有 5000 个请求, 服务器的大量资源都会浪费在建立连接上,而不是执行业务。
1.3 建立一个连接到底需要做什么?
以 MySQL 为例:
Application
│
▼
TCP 三次握手
│
▼
SSL/TLS(可选)
│
▼
MySQL 用户认证
│
▼
权限校验
│
▼
初始化 Session
│
▼
返回连接对象
这整个过程远比执行一条简单 SQL 更耗时。
例如:
建立连接 30ms
执行 SQL 5ms
真正执行业务只占很小一部分时间。
1.4 连接池的思想
连接池启动时: 比如创建 10 个连接:Conn1,Conn2…Conn10
请求到来:
Request->获取 Conn3->执行 SQL->归还 Conn3
连接不会关闭,而是返回池中,等待下一个请求继续使用。
1.5 企业中的连接池
几乎所有企业项目都会使用连接池。 比如:
- MySQL
- Redis
- RabbitMQ
- HTTP Client
二、原理
2.1 连接池的生命周期
一个连接通常经历以下几个阶段:
创建连接
│
▼
加入连接池
│
▼
等待请求
│
▼
借出连接
│
▼
执行业务
│
▼
归还连接
│
▼
继续等待
整个生命周期中:
连接会被多次重复使用。
2.2 请求如何获取连接?
假设:
连接池:
Pool
Conn1
Conn2
Conn3
三个请求同时到来:
Request1
↓
Conn1
Request2
↓
Conn2
Request3
↓
Conn3
第四个请求:Request4->等待 直到:Conn2 ->归还 然后:Request4->获得 Conn2
2.3 为什么连接池能提高性能?
连接建立的成本被摊销,系统吞吐能力显著提升。
2.4 连接池也是一种并发控制
连接池不仅是性能优化工具,也是资源保护机制。
例如:
max_connections = 50
意味着:最多只有 50 个请求,可以同时访问数据库
第 51 个请求:等待空闲连接->等待超时->返回异常
连接池不仅是性能优化工具,也是资源保护机制。
2.5 为什么不能无限创建连接?
数据库本身能够处理的连接数有限。
例如:
MySQL
max_connections = 300
如果应用创建:1000 个连接
数据库将无法承受:
- 内存消耗增加
- 调度压力增加
- 锁竞争增加
因此:
连接池大小应根据:
- 数据库能力
- CPU
- 并发量
综合配置,而不是越大越好。
三、最佳实践
3.1 不要每次创建连接
每次请求重新创建连接。
应交给框架统一管理。
3.2 合理配置连接池大小
连接池数量 ≤ 数据库 max_connections
并预留一部分连接供管理工具、运维脚本等使用。
3.3 避免长事务
长事务会长期占用连接,导致连接池耗尽。
3.4 使用连接健康检查
长期运行的服务可能出现:
- 数据库重启
- 网络闪断
- 空闲连接失效
因此需要:
- 心跳检测(Heartbeat)
- 自动重连
- 空闲连接回收
3.5 区分不同连接池
不要让所有业务共用一个连接池。