于是翻了下database/sql的数据库连接池的代码实现,看完代码,好像也不是很复杂,但是总觉得理解不够深刻,于是萌生了自己想写个连接池的想法。(最后也验证了,看源码的理解确实不够深刻,一看就会,一做就跪)
2、连接池的实现原理什么是连接池
顾名思义是一个池子
池子里面存放有限数量即时可用的连接,减少创建连接和关闭连接的时间
连接是有存活时间的
具体到数据库连接池,我根据自己的理解画了一张获取连接的流程图
从上图我们可以看出,除了连接池的容量大小,我们还有一个最大连接数的限制。池子里的连接让我们不用频繁的创建和关闭连接,同时应该也要有最大连接的限制,避免无限制的创建连接导致服务器资源耗尽,拖垮服务不可用。
池子中的连接也有存活时间,如果超过存活时间则会销毁连接。
3、实现连接池我们需要考虑哪些问题 3.1 功能点
获取连接
释放连接
Ping
关闭连接池
设置最大连接数和连接池容量(连接存活时间等等)
3.2 实现细节连接应该有哪些属性,比如最大连接数、连接池容量、连接创建时间和存活时间
如何模拟使用连接池以及超过最大连接数后等待其他连接释放
如何保证在多协程操作下数据的一致性
如果实现连接的超时监听和通知
4、具体实现这里的连接池实现包括
设置最大连接数和连接池容量
获取连接
释放连接
4.1 结构定义定义Conn结构体,这里包含了几乎所有的有关连接需要的信息属性
type Conn struct { maxConn int // 最大连接数 maxIdle int // 最大可用连接数 freeConn int // 线程池空闲连接数 connPool []int // 连接池 openCount int // 已经打开的连接数 waitConn map[int]chan Permission // 排队等待的连接队列 waitCount int // 等待个数 lock sync.Mutex // 锁 nextConnIndex NextConnIndex // 下一个连接的ID标识(用于区分每个ID) freeConns map[int]Permission // 连接池的连接 }