连接池

关注
义项:数据库连接复用的技术机制
连接池

连接池是数据库连接复用的一种技术机制,它在应用程序启动或首次访问时预先建立若干数据库连接并集中存放于一个「池」中,应用需要时从池中取出连接,用完后归还,而不是每次操作都新建、关闭连接。建立数据库连接涉及网络握手、身份认证与会话初始化等步骤,开销较大,连接池通过复用已有连接减少这部分开销,同时限制应用与数据库之间的连接总数。它已成为 Web 应用等高并发系统的常见基础设施。

百科 图文
目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

连接池是一种创建和管理数据库连接的技术,把一批已建立好的连接保存在池中,供任何需要它们的线程使用[1]。其核心是连接的复用:应用程序不再每次操作都新建连接,而是向池请求一个可用连接,使用完毕后再把它交回池中。

同类的池化技术还有线程池、HTTP 连接池、Redis 客户端连接池等,它们的共同点是把创建代价高的资源放进容器中反复使用,以空间换取时间[2]。在数据库访问领域,连接池充当应用程序与数据库服务器之间的中间层,负责连接的分配、管理与释放[3]。

原理

一个数据库连接在物理上对应一条到数据库服务器的会话,它的建立包含 TCP 三次握手、数据库身份验证和会话初始化等步骤,耗时通常在数十毫秒量级。在不使用连接池的模式中,每次访问都经历「创建连接、执行语句、取回结果、销毁连接」的完整流程;使用连接池后,除了第一次访问需要建立连接外,后续请求基本复用已有连接。

连接的取用与归还遵循固定的流程。线程需要执行数据库操作时,先向池申请连接;池中若有空闲连接就直接返回,若没有且连接总数未达上限,则尝试新建,若已达上限,请求进入等待状态。操作完成后,应用调用关闭方法,但物理连接并不真正断开,而是被标记为空闲、清理状态后放回池中,供其他线程使用[4]。

池中通常包含三类数量指标:打开连接数为空闲连接与使用中连接数之和,使用中连接数指正在执行查询或处于事务中的连接,空闲连接数指已建立但当前没有任务的连接。设单个应用实例的连接上限为 P、实例数为 N、后台任务与管理工具预留连接为 R,则应用可能产生的连接总量约为:

$P \times N + R \le 数据库可稳定承载的连接量$

连接池常借助事件监听机制感知连接状态。以 JDBC 的实现为例,池实现类向物理连接注册监听器,当连接被关闭或发生错误时收到通知,据此决定把连接放回池中还是将其销毁。

发展历程

连接池的概念随着 Java 数据库访问技术的发展而标准化。JDBC 1.0 通过 DriverManager 直接与数据库建立连接,这种方式要求代码写入厂商相关的驱动类名和数据库地址,也不支持连接复用[5]。JDBC 2.0 把 API 拆分为 java.sql 与 javax.sql 两个包,在扩展包中引入 DataSource 接口,把连接池、分布式事务、行集等特性纳入标准[6]。

在标准接口层面,javax.sql.ConnectionPoolDataSource 被定义为产生池化连接的工厂,javax.sql.PooledConnection 封装到数据库的物理连接,应用从中获得的则是一条逻辑连接,作为物理连接的临时句柄[4]。关闭逻辑连接不会断开物理连接,真正关闭物理连接需要调用池化连接自身的关闭方法[7]。

此后出现了多种具体实现。早期较有代表性的包括 Apache Commons DBCP、c3p0 和 Proxool 等,它们奠定了池化的基本模式。Apache 社区后来用 Commons Pool 与 Commons DBCP 2 继续维护其实现,Tomcat 也长期把 DBCP 作为连接池组件,并在 7.0.19 版本之后随包集成了名为 tomcat-jdbc 的连接池[8]。DBCP 2 于 2014 年发布[8]。

以线程模型划分,采用单线程同步架构的实现常被归为第一代,采用多线程异步架构的被视为第二代。HikariCP、Druid 等较新的实现更注重并发性能与可观测性,其中 HikariCP 通过减少锁竞争来提升高并发下的表现,Druid 提供了较全面的监控与统计能力。

应用

连接池最典型的使用场景是高并发、高负载的 Web 应用。这类系统的请求生命周期短、访问频次高,若每条请求都独立建连,连接开销会占据相当比例的系统资源[2]。电商网站等系统在启动时先创建连接池,用户请求到达后由后端程序从池中取得连接、执行操作,再归还池中[9]。

在 Java 生态中,应用通常先在应用服务器或框架的配置文件中设定连接池参数,再通过 Java 命名和目录接口(JNDI)查找数据源来获取连接[10]。连接池既可以内置于应用自身的数据库访问库中,也可以以独立进程的形式部署在数据库之前,后者常被称为服务端池化器,用于应对无服务器函数等会大量产生短生命周期连接的场景[11]。

连接池的容量需要按业务负载估算。一种做法是先用压测工具把最大连接数设为不受限,测出并发使用连接数的峰值,再据此反推最小与最大连接数的合理取值[10]。也有以平均占用时间为依据的估算方式:平均并发连接需求约等于每秒数据库操作数与单次连接平均占用秒数之积。运行中可通过监控打开连接数、使用中连接数、空闲连接数、等待次数与等待时长等指标判断池是否偏小或偏大。

局限

连接池并不能免除对连接的管理责任。应用程序仍需在使用完毕后主动关闭所取得的连接,且不应把关闭动作拖延到对象回收阶段;同样,连接也不宜作为静态成员变量或跨线程共享的实例变量使用,否则可能出现多个线程共用同一条连接的情况[12]。

连接泄漏是与此相关的主要风险。当应用取得连接后未正确归还,池中可用连接会逐渐减少直至耗尽,新请求只能长时间等待或直接失败。池耗尽可能由突发流量、慢查询累积或下游系统故障引发,一条耗时很长的查询并发执行时会快速占满连接,使其他正常请求在池边排队直至超时[13]。

池的大小并非越大越好。每个连接在客户端和服务器端都会带来内存、CPU 和上下文切换等开销,连接数过多会加剧数据库的锁竞争与资源争用,反而降低整体吞吐;设置过小则会导致请求长时间等待连接[10]。连接池解决的是建连开销问题,并不等同于提升数据库的并发处理能力。

连接的有效性也需要额外机制保障。长时间空闲的连接可能已被数据库或网络断开,若不加检测,应用可能取到失效连接而导致操作失败,因此通常需要在借出前、归还时或定期检查连接是否仍可用[10]。此外,池中的空闲连接会持续占用内存等资源,配置与监控本身也构成一定的维护成本[14]。

参见

  • 线程池 —— 与连接池同属池化技术,复用创建代价较高的线程资源。

  • JDBC —— 定义连接池相关标准接口的 Java 数据库访问规范。

  • 数据源 —— 应用程序获取池中连接的抽象接口。

  • 数据库 —— 连接池所服务的数据存储系统。

  • 事务 —— 执行期间会独占一条连接,其时长直接影响池的占用。

参考资料

  1. 第 8 章 使用 Connector/J 的連線池 [引用日期2026-10-14]
  2. aliyun.com 上的网页 [引用日期2026-10-14]
  3. aliyun.com 上的网页 [引用日期2026-10-14]
  4. connpoca [引用日期2026-10-14]
  5. DataSource,一个被严重低估的接口 [引用日期2026-10-14]
  6. 走进JavaWeb技术世界3:JDBC的进化与连接池技术 [引用日期2026-10-14]
  7. Connection Pooling and Caching [引用日期2026-10-14]
  8. Re: Tomcat DBCP 8.0.18 issue-Apache Mail Archives [引用日期2026-10-14]
  9. 数据库连接池:从JDBC到高效管理的演进 [引用日期2026-10-14]
  10. 第 8 章 使用 Connector/J 进行连接池 [引用日期2026-10-14]
  11. Connection pooling and limits | Supabase Docs [引用日期2026-10-14]
  12. 96.114 上的 PDF 文件 . 96.114 [引用日期2026-10-14]
  13. 数据库连接池参数调优:一次慢查询引发的复盘 [引用日期2026-10-14]
  14. jdbc连接池有什么好处坏处 [引用日期2026-10-14]
词条评价
词条统计

浏览次数:2 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-13T23:17:08Z

历史版本

本条目引用的词条
线程池 JDBC 数据源 数据库 事务