C++手撕连接池-创新互联

用c++写一个数据库连接池

创新互联是专业的高密网站建设公司,高密接单;提供成都网站制作、成都网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行高密网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

数据库连接池是为了提高数据库连接的性能,进行连接复用

对于复杂数据库进行大量引用的场景下就会出现访问瓶颈

常见的两种解决方法就是:为了减少磁盘 I/O的次数,在数据库和服务器的应用中间加一层 缓存数据库(例如:Redis、Memcache);
或者就是增加连接池,来减少高并发情况下大量 TCP三次握手、MySQL Server连接认证、MySQL Server关闭连接回收资源和TCP四次挥手 所耗费的性能。

机制解读:

连接池呢就是为数据库连接建立一个缓冲池。
1:从连接池获取或创建可用连接
2:使用完毕之后,把连接返回给连接池
3:在系统关闭前,断开所有连接并释放连接占用的系统资源
4:能够处理无效连接,限制连接池中的连接总数不低于或者不超过某个限定值

池子里四个基本属性:

初始连接量(init_size): 表示连接池事先会和MySQL服务器创建init_size个connection连接,当应用发起MySQL访问时,不用再创建和MySQL服务器新的连接,直接从连接池中获取一个可用的连接就可以,使用完成后,并不去释放connection,而是把当前connection再归还到连接池当中。

大连接(max_size): 当并发访问MySQL服务器的请求增多时,初始连接量已经不够使用了,此时会根据新的请求数量去创建更多的连接给应用去使用,但是新创建的连接数量上限是max_size,不能无限制的创建连接。因为每个连接都会占用一个socket资源,一般连接池和服务器程序是部署在一台主机上的,如果连接池占用过多的socket资源,那么服务器就不能接收更多的客户端请求了。当这些连接使用完成后,再次归还到连接池当中来维护。

大空闲时间(max_idle_time): 当访问MySQL的并发请求多了以后,连接池里面的连接数量会动态增加,上限是max_size个,当这些连接用完再次归还到连接池当中。如果在指定的max_idle_time里面,这些新增加的连接都没有被再次使用过,那么新增加的这些连接资源就要被回收,只需要保持初始连接量init_size个连接就可以了。

连接超时时间(connection_timeout): 当MySQL的并发请求量过大,连接池中的连接数量已经到达max_size了,而此时没有空闲的连接可供使用,那么此时应用无法从连接池获取连接,它通过阻塞的方式等待获取连接的时间如果超过connection_timeout时间,那么连接失败,无法访问数据库。

技术点的分析:

通过预先创建一定数量的连接,放到一个池子。当客户端有请求时,服务器端需要与mysql进行交互,那么只需要从池子里取出一个连接,当操作完成再将连接放到连接池中。如此以来避免了频繁的创建和销毁线程。

1.池子只需要一个就够用了,一个池子里有很多连接了。所以对于线程池这个类而言使用单例模式最为合适。用c++11内部静态变量这种线程安全的方法做的

2.池子里面连接存在类似队列这种容器里面,直接用queue了,每次新的连接从队尾进去,队头的连接用完之后,如果空闲太久,占资源就需要把他销毁掉

3.进行数据库连接的话需要mysql相关的api,用c++的话,就把这些api封装一下,具体常用的api之前有写过一篇博客 C/C++链接mysql_

这封装成一个数据库连接类,里面就是伴随着数据库的初始化,查询,更新,事务的一系列操作。连接池里面队列放的就是这一个个数据库连接的类对象

4.需要访问数据库的线程从连接池里面取出连接,和给池子里添加新连接的线程构成了一个典型的生产者消费者,用条件变量加+互斥锁保证同步,cas原子操作 定义一个连接池内的连接数量,用来当做我们生产和消费线程工作都要参考的变量,变量必须保证其原子性

5.对于获取连接池中的连接来说,用户只需要关心使用,去连接池里直接获取连接并且使用即可,并不用关心连接的生成和销毁,并且,对于使用完的连接来说,为了达到复用的目的,我们并不希望把它释放掉,而是使用完之后将其放回到连接池中供其他消费者使用,这个我们就可以使用智能指针来完成用lambda表达式定制连接释放的功能,(把连接重新还给池子);重新放进连接池呢就是重新push到队列池子里,不过要更新一下时间戳,记录每个连接的存活时间

6.连接池实现自动管理连接数(不够时创建连接,销毁空闲时间较长的连接)

需要通过两个子线程,因为主线程不能阻塞在这个地方,所以通过两个子线程取完成,设置线程分离

一个子线程用来不够时自动创建连接:

  线程池维护了两个数据,一个最小连接数,一个大连接数

一个子线程用来销毁空闲时间较长的连接:

  大概实现思路:从队头取出连接,并将该连接的空闲时长与设定的大空闲时长比较,如果大于等于就从队列中弹出并销毁

7.利用Jsoncpp库去解析json文件,配置环境

整个流程原理大概就这样

当时做了四组压力测试:

一个线程去连接数据库每次插一条数据,测试5000下

用连接池省了和数据库建立连接的损耗 

多线程的话,测了五个线程(好比五个用户)不断的去同时连接数据库,每次连接插入一条数据,一共插5000条

接上连接池,效率更高

测了5000条数据,能很明显的看到单线程多线程下使用连接池,访问速度有着明显的提高

总结:深入了解了池化的技术,可以和线程池配套,作为一个不错的项目

源码放在这了:Xw-oorik

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧

本文题目:C++手撕连接池-创新互联
路径分享:https://www.cdcxhl.com/article2/hhhoc.html

成都网站建设公司_创新互联,为您提供网站排名搜索引擎优化定制网站品牌网站建设域名注册外贸网站建设

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

外贸网站制作