对于共享资源,有一个很著名的设计模式:资源池(Resource Pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。数据库连接池的基本思想就是为数据库连接建立一个“池”子,在使用的时候,从“池子”中获取资源,用完后将连接放回“池子”,减少了数据库连接建立与释放造成的损耗。
而对于PHP而言,每一个请求过来都是由php-fpm调起来一个cgi来处理,处理完后就会被释放,所以并没办法在代码中实现连接池的,但是由运行方式,我们可以自然而然的推想,既然php-fpm是常驻内存的,那我们将数据库连接交给php-fpm托管,也就实现了理论上的数据库连接池,而这种实现方式也就是MySQL的pconnect的实现方式,而且经测试,效果并没有显著的提升。那么,接下来便可以考虑基于Swoole的常驻内存的特性来帮忙实现了
思路
- 首先基于Swoole的channel实现一个内存队列 quene,(也可以通过php的共享内存实现,这里不讨论这种方式),用于存放MySQL连接的线程id,thread_id
- 建立一定数量的MySQL连接存放在数组中,然后将 thread_id(mysqli::$thread_id)推进内存队列 quene,
- 每个请求过来的时候,从quene中 pop 出一个 thread_id, 根据thread_id找到对应数组中对应的数据库连接
- 请求结束后,将thread_id再push进quene
代码实现
数据库连接管理者
这个类是用来管理连接的,增加和删除以及获取链接使用
1 | class MysqlConnections { |
内存队列
这里是以数据库连接属性的thread_id 组成的内存队列
1 | class Quene { |
数据库连接池
结合上面的连接管理者和队列,实现对连接的分发和归还
1 | class DbPool { |
Swoole Http Server
基于swoole开启一个http server,获取相应的数据库连接,并相应
1 |
|
测试
ab -n 10 -c 5 http://127.0.0.1:9502/
结果
1 | add 6879 into pool |
完美符合预期