实现一个协程版的mysql链接池,该链接池支持自动建立最小链接数,自动检测mysql健康;基于swoole的chanel。
最近事情忙,心态也有点不积极。技术却是没有落下,只是愈来愈不想写博客了。想到平时本身上网上找资料的痛苦,因而将本身这篇链接池的文章放出来,给须要的程序员一点帮助。php
<?php /** * 实现一个协程版的mysql 链接池 * Created by PhpStorm. * User: roverliang * Date: 2018/12/10 * Time: 23:27 */ namespace console\libs; use Swoole\Coroutine\MySQL as coMysql; use Swoole\Coroutine\Channel; class CoMysqlPool extends coMysql { protected $maxNums; //最大链接数 protected $minNums; //最小链接数 protected $mysqlConfig = array( 'host' => '127.0.0.1', 'port' => 3306, 'user' => 'root', 'password' => '', 'database' => 'hifuli', 'timeout' => -1, ); //mysql配置 protected $chan; //channel protected $currentConnectedNums; //当前链接数 protected $tag; //标识 /** * 初始化链接池 * CoMysqlPool constructor. * @param int $maxNums 最大链接数 * @param int $minNums 最小链接数 * @param array $mysqlConfig mysql配置 */ public function __construct($maxNums = 20, $minNums = 5, $mysqlConfig = []) { $this->maxNums = $maxNums; $this->minNums = $minNums; if (!empty($mysqlConfig) && is_array($mysqlConfig)) { $this->mysqlConfig = $mysqlConfig; } $this->chan = new Channel($maxNums); $this->tag = true; } /** * 从链接池中获取一个mysql链接对象 * Created by 梁子(roverliang) <mr.roverliang@gmail.com> * 2018/12/10 */ public function pop() { if (!$this->tag) return false; if ($mysql = $this->getMysqlInstance()) { echo "建立了一个mysql".PHP_EOL; return $mysql; } $mysql = $this->chan->pop(); if (!$this->checkMysqlHealth($mysql)) { $mysql = $this->getMysqlInstance(); } else { echo "复用mysql".PHP_EOL; } return $mysql; } /** * 将mysql对象放回链接池 * Created by 梁子(roverliang) <mr.roverliang@gmail.com> * 2018/12/10 * @param $obj */ public function push($mysql) { if (!$this->tag) return false; if (!$this->chan->isFull()) { echo "将mysql放入链接池".PHP_EOL; $this->chan->push($mysql); } return true; } /** * 获取mysql实例 * Created by 梁子(roverliang) <mr.roverliang@gmail.com> * 2018/12/10 * @return bool */ protected function getMysqlInstance() { if (!$this->chan->isFull()) { $mysqlInstance = new \Swoole\Coroutine\MySQL(); $mysqlInstance->connect($this->mysqlConfig); return $mysqlInstance; } return false; } /** * 检测mysql链接是否健康 * Created by 梁子(roverliang) <mr.roverliang@gmail.com> * 2018/12/10 */ protected function checkMysqlHealth($mysql) { if (!$mysql->connected) return false; return true; } /** * 销毁链接池 * Created by 梁子(roverliang) <mr.roverliang@gmail.com> * 2018/12/11 */ public function destroyPool() { $this->tag = false; while ($this->chan->length()) { $mysql = $this->chan->pop(); $mysql->close(); echo "销毁mysql".PHP_EOL; } return true; } /** * 监控进程池 * Created by Roverliang. * Date: 2018/12/12 Time: 17:12 */ public function monitorPool() { declare(ticks=10); $self = $this; register_tick_function(function () use ($self) { if (($self->chan->length() < $self->minNums) && $self->tag) { $mysql = $self->pop(); if ($self->checkMysqlHealth($mysql)) { echo "mysql进程监控池自动建立mysql".PHP_EOL; $self->push($mysql); } } }); } } go(function(){ $mysqlPool = new CoMysqlPool(10, 2); $mysqlPool->monitorPool(); for($i=0; $i<20;$i++) { $mysqlPool->monitorPool(); $mysql = $mysqlPool->pop(); $mysqlPool->push($mysql); \Swoole\Coroutine::sleep(1); } $mysqlPool->destroyPool(); });