连接池原理简述

概述

数据库连接池的原理,跟线程池一样都是通过重用资源来提升性能。(线程池重用的是线程资源,连接池重用的是连接,避免连接频繁的创建和销毁,减少了cpu,内存,网络开销),本文主要简单讲述连接池的原理。

数据库连接的生命周期

让我看看连接一次数据库要经历哪些步骤

  1. 用 database driver 打开一个连接去连接数据库
  2. 打开一个 TCP socket 读写数据
  3. 数据读写完毕
  4. 关闭连接
  5. 关闭socket

可以看出进行一次数据库连接是个相当昂贵的操作。

没有连接池的情况

图片来自博客 https://blog.youkuaiyun.com/shuaihj/article/details/14223015

如上图,如果没有连接池,这时候应用有15万个并发用户操作(包括读写)那么就会创建很多连接到数据库,这样频繁的创建连接又销毁即浪费了cpu,内存资源,又会造成数据库连接过多而报错。(MySQL 5.7 最大连接数 是 10万,默认是 151)

有连接池的情况

图片来自博客 https://blog.youkuaiyun.com/shuaihj/article/details/14223015

如上图,假设连接池最大连接数是 200 ,现在程序有 15万 个并发sql操作(包括读写,相当于某个电商促销活动,有15万人在线操作,这个量级(阿里,唯品会等)很容易达到),这个时候,他们就会轮换使用这 200 个连接来执行sql,这样连接池和数据库的连接最多200个, 不会创建过多连接。这样使用连接池即减少了连接频繁地创建和销毁,又避免了过多连接打垮数据库,并且每次创建销毁一个连接大概 0.05s~1s(MySQL) ,相当于每个sql操作都多几十到几百毫秒,这很明显是没对的。

了解连接池原理的好处

  • 懂得如何配置最大连接数了(不要超过数据库最大连接数,当然也不是越大越好,最大连接数一般跟最大线程池数一样,设置成 cpu核心数*2 就行了,具体参考 https://blog.youkuaiyun.com/w05980598/article/details/78797310/ 文章)
  • 知道了资源池设计模式:即资源池设计模式是用来解决资源频繁创建和销毁带来的浪费问题。比如数据库连接池, 线程池等等。后续遇到同样场景的问题,就可以用此设计模式来解决。

参考

https://blog.youkuaiyun.com/shuaihj/article/details/14223015

转载于:https://my.oschina.net/anuodog/blog/3035518

### 数据库连接池的工作原理 数据库连接池是一种用于优化数据库访问的技术,其核心目的是通过复用已有的数据库连接来减少频繁创建和销毁连接带来的性能开销。以下是关于数据库连接池工作原理及其实现机制的具体描述: #### 1. 连接池的核心概念 数据库连接池本质上是一个容器,用来管理和维护一组预先创建好的数据库连接。当应用程序需要执行数据库操作时,可以从连接池中获取一个可用的连接;完成操作后,将连接归还给连接池而不是直接关闭它[^2]。 #### 2. 工作流程 - **初始化阶段** 在程序启动时,连接池会根据配置参数(如初始连接数、最大连接数等),提前创建一定数量的数据库连接并存放在内部的数据结构中(通常是队列或线程安全的集合)。这些连接处于待命状态,随时可以被借用[^4]。 - **借取连接** 当业务逻辑请求数据库服务时,连接池会从现有的空闲连接列表中选取一个未使用的连接供调用方使用。如果当前没有空闲连接,则可能采取以下几种方式之一: - 如果允许等待,则让调用者进入阻塞状态直到有新的空闲连接出现; - 或者抛出异常告知无法继续处理请求; - 若支持动态扩展,则尝试新增额外的连接以满足需求[^3]。 - **释放连接** 完成数据交互之后,客户端应显式地通知连接池结束本次会话并将占用的链接交还回去。此时该连接并不会真正断开而是重新标记为“可借用”,以便后续其他事务重用[^4]。 #### 3. 实现细节分析 为了更好地理解其实现过程,这里给出一段简单的自定义 MySQL 数据源类 `MyDataSource` 的 Java 示例代码展示如何构建基本功能版本的连接池: ```java import java.sql.Connection; import java.sql.SQLException; import java.util.LinkedList; public class MyDataSource implements javax.sql.DataSource { private LinkedList<Connection> pool = new LinkedList<>(); public MyDataSource(int initialSize) throws SQLException { for (int i = 0; i < initialSize; ++i) { pool.add(JdbcUtil.createConnection()); } } @Override public synchronized Connection getConnection() throws SQLException { while (pool.isEmpty()) { try { wait(); } catch (InterruptedException ignored) {} } return pool.removeFirst(); } public synchronized void releaseConnection(Connection connection){ if(connection != null && !connection.isClosed()){ pool.addLast(connection); notifyAll(); } } } ``` 此示例展示了基于链表结构模拟简单形式下的 FIFO 队列行为,并且包含了同步控制语句确保多线程环境下的安全性[^4]。 #### 4. 关键特性与优势 - 提升效率:减少了每次新建/销毁物理连接所需的时间成本。 - 资源管控:能够有效限制并发量从而保护后台服务器免受过多负载冲击。 - 故障恢复能力增强:部分高级别的解决方案还可以集成心跳检测等功能,在发现失效实例时自动替换掉它们[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值