为什么要使用连接池?

Druid是我们最常听到的连接池,之前提到一个问题,如果无限创建连会怎么样?一般来说数据库都会限制连接数,连接保持意味着占用一部分宝贵的资源,比如线程内存。

前面的demo中也可以看到在使用完毕Connection后,会调用close方法去关闭这个连接,并且释放资源。

但是会引入一个新的问题,连接的创建和关闭是一个不稳定的操作,在某些客户环境下创建一个连接并建立通信要花费好几秒,如果每次查询都重新创建连接,这样的性能损耗累积起来实在太大。

所以如果我们创建连接后,持有这个连接进行多次查询这样就能节省一大块时间。这就是连接复用。

这就是连接池的作用,减少连接创建开销,尽可能在需要查询时提供可用的连接

连接池的工作原理

连接池要实现的目标除了刚才说的连接复用,也会带来一个问题,当空闲的时候连接一直维持着,这样数据库端的资源也没有释放。

因此一个好的连接池必须具备以下几个特点:

  • 能连接复用减少创建开销

  • 能控制连接数量减少对数据库的影响

  • 能够值守无需创建随时可用

有了这三条准则,我们可以自己实现一个连接池,不信?来试试:

  • 创建一个池子;

  • 我们给池子创建10个初始连接(initSize),提供给业务使用,通常也够用了;

  • 为了应付高峰查询,我们允许连接池短暂的存在100个连接(maxSize),但是到低谷都要关闭;

  • 连接一般是tcp或者http等实现的,它是有生命周期的比如socketTimeout,会被数据库或者网络波动影响关闭,因此我们需要一个连接检查器(连接校验)检查连接是否畅通;

  • 如果空闲时突然来了一个查询,此时连接都被数据库关闭了,连接检查后(连接前校验),还是要重新创建,这个开销就不可避免,所以我们可以在空闲的时候定时检查(空闲检测testWhileIdle)一下连接,如果关闭就重新创建一个放在池子里;

  • 为了防止连接占有资源,我们需要在空闲的时候释放至最小连接数(minIdle),需要配置一个空闲时间(idleTime),达到空闲时间后连接池主动关闭;

这个过程,大家应该看到一些我们熟悉的概念了,比如连接池大小、空闲检测、连接检查器等;实际上所以的连接池基本上都会具备这些特点,也可以自定义去设置参数大小以满足业务的真实需求;

常见的连接池

在Druid之前,我们使用的是经典的DBCP连接池,但是DBCP性能不佳,改用了高性能的Druid。

现在比较常用还有HikiraCP等。

偷得浮生半日闲,心情半佛半神仙。