你真的熟悉数据连接池吗?手写实现连接池
Posted 阿甘正专
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你真的熟悉数据连接池吗?手写实现连接池相关的知识,希望对你有一定的参考价值。
点击关注“阿甘正专”,设为星标
奇迹每天都在发生,等你而来
引言
一、数据库连接池简介↑
常见池化技术:
线程池:管理线程对象的池
对象池:初始化一些对象的池,如jdk的静态常量池、运行时常量池等
连接池:管理连接对象的池
常见:
1、C3PO-开源连接池,Hibernate,Spring
2、BonecP--apache出品tomcat使用
3、Druid--阿里出品,史上最强没有之一,对所有sql的监控
4、HikaricP--springboot2,java最快连接池
什么东西需要池化技术?
有限资源-数据库连接,计划分配,资源管控,减少开销
开销大/耗时-线程池,开辟栈空间,创建/销毁开销大
场景(运营)需求:
1、管理mysql连接
2、200并发量
3、MySQL Pool最大连接数为10---限流
4、服务对象维护
https://blog.csdn.net/wangjunjie0817/article/details/89380841
资源重用
更快的系统响应速度
新的资源分配手段
统一的连接管理,避免数据库连接泄漏
JDBC最常用的资源有三类:
Connection: 数据库连接
Statement: 会话声明
ResultSet: 结果集游标
举个例子: 如果想确定某个数据库连接(Connection)是否超时,则需要确定其(所有的)子Statement是否超时,同样,需要确定所有相关的 ResultSet是否超时;在关闭Connection前,需要关闭所有相关的Statement和ResultSet。因此,连接池(Connection Pool)所起到的作用,不仅仅简单地管理Connection,还涉及到 Statement和ResultSet。
初始化:预先创建好对象,放入池中
设定最大数,防止无尽连接,资源耗尽
客户端从池中出借空闲连接对象
客户端归还连接对象回池
体检-自我检测
(1)获取连接 getConnect()
从idle中取出对象,放入busy
Idle有值,直接取
ldle无值,若池子未满,新建
池满全繁忙,等待返还
(2)释放连接 releaseConnect()
从繁忙工作队列中移除对象,放入空闲队列中
二、应用实战↑
新建一个SpringBoot应用:mini-pool
maven 主要依赖,jdbc连接mysql的驱动
新建一个创建jdbc连接的工具类
注:实际项目中,配置信息要填写在配置文件中,这里为了方便演示,就直接写死再代码中了。
新增一个 MiniPool 简单的连接池接口,包含如下方法:初始化、销毁连接、获取连接、释放连接等
MiniPoolImpl 实现 MiniPool接口方法
@Slf4j
public class MiniPoolImpl implements MiniPool {
// 空闲连接队列
private LinkedBlockingQueue<Connection> idleQueue;
// 工作中队列
private LinkedBlockingQueue<Connection> busyQueue;
// 连接池最大数量
private final int maxSize;
// 存活的连接数,一开始默认0
private AtomicInteger activeSize = new AtomicInteger(0);
public MiniPoolImpl(int maxSize){
this.maxSize = maxSize;
}
/**
* 初始化连接池
*/
@Override
public void init() {
idleQueue = new LinkedBlockingQueue<Connection>();
busyQueue = new LinkedBlockingQueue<Connection>();
}
/**
* 销毁
*/
@Override
public void destory() {
}
其中,释放连接方法:
主要是获取连接方法:
(1)判断空闲队列是否有值,有直接取返回
(2)若空闲队列无值,而且连接池未满,则新建一个连接
(3)连接池全繁忙工作中,阻塞等待一定时间返回
其中,第2步同步代码块部分,可使用原子类 AtomicInteger 优化
// 存活的连接数,一开始默认0
private AtomicInteger activeSize = new AtomicInteger(0);
注意:
activeSize.get() 获取当前活跃连接数
activeSize.incrementAndGet() 先加1再获取(原子操作)
这里,因为 activeSize.incrementAndGet() 比 activeSize.get() 性能高,所以双重判断比只用 activeSize.incrementAndGet() 判断好,锁的双重判断。
配置注册到Spring容器管理:
编写测试类Controller,新增一个http接口方法,便于发送http请求
具体的业务逻辑测试类,因为要模拟200并发访问,使用多线程技术模拟,业务处理只是简单地往数据库插入200条数据,主要是观察日志输出,是否有需要排队等待获取连接的情况,最好是打断点观察。
注:这里为了简单测试,就不写接口了。
(1)t_user表数据清空
(3)查看数据库,已经成功插入200条数据
参考资料:
享学课堂公开课
https://blog.csdn.net/wangjunjie0817/article/details/89380841
●
●
●
●
●
●
●
●
右上角按钮分享给更多人哦~
来都来了,点个在看再走吧~~~
以上是关于你真的熟悉数据连接池吗?手写实现连接池的主要内容,如果未能解决你的问题,请参考以下文章