基于Swoole2协程特性实现的MySQL连接池

799 阅读3分钟

使用Swoole2的\ Swoole \ Coroutine \ MySQL创建连接,通过静态类和静态成员属性维护连接池,不同协程可以共享该连接池。

排队机制(先进先出)使用协程的特殊功能实现:

  • \Swoole\Coroutine::resume(name):从 name):从 name域名中恢复一个挂起的协程执行;

  • \Swoole\Coroutine::suspend(name):将当前协程挂轴向 name):将当前协程挂轴向 name本身上。

限制条件

  • 每个worker都有各自的MySQL连接池,并且不同worker之间无法共享彼此的MySQL连接池;

  • 可能存在各个worker进程连接池最大化不同(依赖业务实现)。

优点

  • 与独立的连接池(worker进程间可共享的连接池实现)对比,无进展间通信开销;

  • 独立的连接池需要增加运维成本。

使用方法

/ ** 
*初始化连接池
* 
* @param array $ connsConfig配置数组
* [ 
*'connName1'=> [ 
*'serverInfo'=> ['host'=>'127.0.0.1''user'=>'测试''password'=>'pass''database'=>'tt''charset'=>'utf8'],// \ Swoole \ Coroutine \ MySQL的连接参数
*'maxSpareConns'=> 5,/ /最大链接连接数
*'maxConns'=> 10//最大连接数
*],
*'connName2'=> [ 
*'serverInfo'=> ['host'=>'127.0.0.2''user'= >'test''password'=>'pass''database'=>'tt''charset'=>'utf8'],// \ Swoole \ Coroutine \ MySQL的连接参数
*'maxSpareConns'=> 5//最大连接数
*'maxConns'=> 10//最大连接数
*],
*] 
* / 
Swoole \ Coroutine\ Pool \ MySQLPool :: init(数组$ connsConfig)

/ ** 
*回收连接,该连接必须是从连接池中获取的连接
** 
@param \ Swoole \ Coroutine \ MySQL $ conn从连接池中获取的连接
* / 
Swoole \ Coroutine \ Pool \ MySQLPool :: recycle( \ Swoole \ Coroutine \ MySQL  $ conn)

/ ** 
*从连接池中获取一条连接
* 
* @param string $ connName init时配置的连接,根据连接名称获取对应的连接
* @return \ Swoole \ Coroutine \ MySQL返回一个连接实例
* / 
Swoole \ Coroutine \ 池 \ MySQLPool :: 提取($ connName)

使用示例

<?php 
需要 'MySQLPool.php' ;
使用 Swoole \ Coroutine \ Pool \ MySQLPool ;

$ server =新的 Swoole \ Http \ Server( “ 127.0.0.1”, 9502, SWOOLE_BASE);
$服务器 - >组([
         'worker_num' => 1,
]);
$服务器 - >上( '请求',功能( $请求, $响应){
         MySQLPool :: INIT([
                 '测试' => [
                         'serverInfo' => [ '主机' => '192.168.244.128' , “用户' => 'mha_manager', 'password' => 'mhapass', 'database' => 'tt', 'charset' =>'utf8' ],
                        'maxSpareConns' => 5,
                         'maxConns' => 10
                ],
        ]);
        $ swoole_mysql = MySQLPool :: fetch( 'test');
        $ ret = $ swoole_mysql- >查询( 'select sleep(1');
        MySQLPool ::回收( $ swoole_mysql);
        $ response- > end( 'Test End');
});
$ server- > start();

压测命令:ab -c 20 -n 100 -s 100 http://127.0.0.1:9502/,20并发,共100个请求。

压测结果:

在这里插入图片描述

压测时连接情况,20并发,最大连接数限制为10,所以最多只会与数据库建立10条连接:

压测后连接情况,设置了最大数量连接数为5,所以现在没有客户端请求时,大部分连接数维持为5:

这里服务端只有1个worker进程在工作,完成100个请求,并且每个请求的SQL查询是sleep 1秒,花了约11秒,如果是php-fpm + mysqli这样的模式,1个worker进程,那么得花100秒。

所以这正是协程的优势所在,利用非双重IO +协程切换,1个worker进程能同时处理多个客户端请求,大大提高了吞吐量。

点关注,不迷路

好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才。之前说过,PHP方面的技术点很多,也是因为太多了,实在是写不过来,写过来了大家也不会看的太多,所以我这里把它整理成了PDF和文档,如果有需要的可以

在这里插入图片描述

在这里插入图片描述

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的 PHP技术交流群