连接池原来这么简单

原创 2017年11月10日 07:53:59

一、如何通过连接访问下游

工程架构中有很多访问下游的需求,下游包括但不限于服务/数据库/缓存,其通讯步骤是为:

1)与下游建立一个连接

2)通过这个连接,收发请求

3)交互结束,关闭连接,释放资源

 

这个连接是什么呢,通过连接怎么调用下游接口?服务/数据库/缓存,官方会提供不同语言的DriverDocumentDemoCode来教使用方建立连接与调用接口,以MongoDBC++官方Driver API为例(伪代码):

DBClientConnection* c = new DBClientConnection();

c->connect(“127.0.0.1:8888”);

c->insert(“db.s”, BSON(”shenjian”));

c->close();

 


这个DBClientConnection就是一个与MongoDB的连接,官方Driver通过它提供了若干API,让用户可以对MongoDB进行连接,增删查改,关闭的操作,从而实现不同的业务逻辑。

 

二、为什么需要连接池

当并发量很低的时候,上述伪代码没有任何问题,但当服务单机QPS达到几百、几千的时候建立连接connect和销毁连接close就会成为瓶颈,此时该如何优化?


结论也很简单,服务启动的时候,先建立好若干连接Array[DBClientConnection],当有请求过来的时候,从Array中取出一个,执行下游操作,执行完再放回,从而避免反复的建立和销毁连接,以提升性能。


这个对Array[DBClientConnection]进行维护的数据结构,就是连接池。有了连接池之后,数据库操作的伪代码变为:

DBClientConnection* c = ConnectionPool::GetConnection();

c->insert(“db.s”, BSON(”shenjian”));

ConnectionPool::FreeConnection(c);

 

三、连接池核心接口与实现

通过上面的讨论,可以看到连接池ConnectionPool主要有三个核心接口:

1Init:初始化好Array[DBClientConnection],这个接口只在服务启动时调用一次

2GetConnection:请求每次需要访问数据库时,不是connect一个连接,而是通过连接池的这个接口来拿

3FreeConnection:请求每次访问完数据库时,不是close一个连接,而是把这个连接放回连接池

 

连接池核心数据结构:

1连接数组Array DBClientConnection [N]

2互斥锁数组Array lock[N]

 

连接池核心接口实现:

Init(){

 for i = 1 to N {

  Array DBClientConnection [i] = new();

  Array DBClientConnection [i]->connect();

  Array lock[i] = 0;

 }

}

说明把所有连接和互斥锁初始化

 

GetConnection()

 for i = 1 to N {

  if(Array lock[i] == 0){

   Array lock[i] = 1;

   return Array DBClientConnection[i];

   }

 }

}

说明找一个可用的连接,锁住,并返回连接

 

FreeConnection(c)

 for i = 1 to N {

 if(Array DBClientConnection [i] == c){

   Array lock[i] = 0;

   }

  }

}

说明找到连接,把锁释放

 


可以发现,简单的连接池管理并不是很复杂,基本原理即如上所述。

 

四、未尽事宜

上述伪代码忽略了一些细节,在实现连接池中是需要考虑的:

1)如果连接全部被占用,是返回失败,还是让上游等待

2)需要实施连接可用性检测

3)为了让调用方更友好,可能还需要包装一层DAO层,让“连接”这个东西对调用方都是黑盒的

4)通过freeArrayconnectionMap可以让取连接和放回连接都达到O(1)时间复杂度

5)可以通过hash实现id串行化

6负载均衡、故障转移、服务自动扩容都可以在这一层实现

版权声明:本文为博主原创文章,未经博主允许不得转载。

连接池原来这么简单

应网友要求,写一写连接池实现细节。   一、如何通过连接访问下游 工程架构中有很多访问下游的需求,下游包括但不限于服务/数据库/缓存,其通讯步骤是为: (1)与下游建立一个连接...
  • xgjianstart
  • xgjianstart
  • 2017年04月01日 11:50
  • 137

连接池原来这么简单(一分钟系列)

应网友要求,写一写连接池实现细节。   一、如何通过连接访问下游 工程架构中有很多访问下游的需求,下游包括但不限于服务/数据库/缓存,其通讯步骤是为: (1)与下游建立一个连接 (2)通过这...
  • DINGYANG0315
  • DINGYANG0315
  • 2017年12月15日 11:10
  • 30

原来这么简单(2)

有一只小鸡在破壳而出的时候,刚好有只乌龟经过,从此以后小鸡就背着蛋壳过了一生。——原来摆脱沉重中的负担很简单,放弃固执成见就可以了。...
  • sagittarius1214
  • sagittarius1214
  • 2005年03月23日 22:50
  • 405

原来这么简单(1)

        住在田边的青蛙对住在路边的青蛙说:“你这里太危险,搬来跟我住吧?”路边的青蛙说:“我已经习惯了,懒得搬了!”几天后,田边的青蛙去探望路边的青蛙,却发现它已经被车子轧死了。——原来掌握命...
  • sagittarius1214
  • sagittarius1214
  • 2005年03月23日 22:49
  • 406

堆排序原来这么简单

给出了堆排序的简要分析和代码实现
  • shineboyxxb
  • shineboyxxb
  • 2016年08月22日 20:06
  • 894

ViewPager+Fragment原来这么简单

我们在使用微信或是网易客户端的时候都会看到下面这样的效果,左右滑动切换页面,点击table栏也可以切换界面,以前看着感觉好高大上,今天用ViewPager和Fragment实现了一下,其实还是蛮好实现...
  • u014733374
  • u014733374
  • 2014年12月18日 16:59
  • 8344

原来这么简单(3)

有几个小孩都很想成为智者的学生,智者给他们一人一个烛台,叫他们保持光亮。结果一天、两天过去了,智者都没有来,大部分小孩都不再擦拭那烛台。有一天,智者突然到来,大家的烛台都蒙上了厚厚的灰尘,只有一个被大...
  • sagittarius1214
  • sagittarius1214
  • 2005年03月23日 22:58
  • 427

原来这么简单。。

/* *Copyright (c++)2015,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:a.cpp *作 者:管毓云 *...
  • gyy20014
  • gyy20014
  • 2015年03月28日 11:18
  • 298

飞信,原来就是这么简单

飞信,原来就是这么简单2009年12月26日 | 分类: 飞信哪些事儿 | 标签:研究飞信是其实是一件很意外的事情。学校科技立项,我有一个很好的想法,就是做一个信息中心,简单的说就像是10086那种短...
  • mirkerson
  • mirkerson
  • 2010年09月26日 17:20
  • 1303

汉化软件,原来这么简单!

汉化软件,原来这么简单!只要把:EXE文件,用二进制编辑器(如:C32ASM)打开,然后在右侧会看到:程序里的一些字样(如:菜单名字),然后把它改为:中文即可,然后另存为:.exe文件,即可!注意:原...
  • HackerJLY
  • HackerJLY
  • 2008年02月20日 00:01
  • 813
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:连接池原来这么简单
举报原因:
原因补充:

(最多只允许输入30个字)