Bootstrap

(面试经典问题之连接池篇)连接池构成、作用及其基本原理详解

一、什么是连接池

连接池一般指的是数据库连接池(connection pooling),是指程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态的对池中的连接进行申请,使用,释放(跟前面文章提到线程池、内存池的概念很像,因为他们都是属于池式结构)。

二、为什么需要数据库连接池

维持管理固定数量的连接,复用连接资源(只要是池式结构,其主要功能就是复用资源):

1、维持与数据库的TCP连接(长连接,而非短连接)(ps:本文的数据库均已MySQL举例);

2、复用连接资源,可复用同一条连接多次执行sql语句,避免了频繁建立和断开tcp连接所需要的资源和时间开销(三次握手建立TCP连接,四次挥手断开TCP连接,读者可以自行回顾一下,看看是否还记得);

3、统一的连接管理,避免数据库连接泄漏;

三、连接池的运行机理

连接池又分为同步连接池和异步连接池,以下将分开进行原理讲解:

同步连接池:

结构如图所示:

工作流程为:用户线程从线程池中获取可用连接(即未被锁定的连接),并同步等待连接的返回(即阻塞当前线程或者当前协程等待返回)。

连接池中的连接数量表示当前最多允许几个用户线程或协程并发使用连接。

应用:服务端启动时,初始化资源需要使用同步连接池。

异步连接池:

结构如图所示:连接池中的连接和线程池中的线程一一对应(即一个线程分配一个连接,是线程池和连接池的共同作用下形成了异步连接池)

工作流程为:用户线程发布任务并将其push进执行任务队列,异步连接池中的线程从队列中取出任务进行消费,消费完成后通过异步回调来通知用户线程获取返回结果。

连接池中的连接数量表示当前允许几个连接同时执行sql语句。(与同步连接池不同,连接数量不代表最多允许几个用户线程或协程并发使用连接,可以是无穷多个用户同时往任务队列里push任务)

应用:服务器启动后的业务处理,一些高并发的业务场景。

四、一些学习中产生的问题及思考

同步连接池性能高还是异步性能高?

按照经验而言,异步往往是性能更高的一方,当然,这个问题中答案也是如此。但是,回答这个问题我们首先要明确主语,即这个性能指的是连接池的性能还是用户线程的性能,性能的直观体现是什么?在此处,性能我们一般默认指用户线程的性能,性能的直观表现就是我用户线程需不需要阻塞等待耗时任务完成,显然,同步连接池就是阻塞线程等待的底层逻辑,而异步线程池则是push任务后直接返回,因此异步的性能更高。

为什么服务端启动时,初始化资源需要使用同步连接池?

上面讲到异步性能更高,但为什么该场景下需要使用同步连接池?原因在于:同步的方案,只有等到任务完成才返回,因此对于用户线程而言,可以明确的知道我的初始化工作是否全部完成,但是异步的方案什么时候返回结果是未知的,而初始化需要确保所有资源、任务都完成,固选用同步连接池。

;