/**
* Class MysqlPoolService mysql连接池
* @package App\Service
*/
class MysqlPoolService
{
use Singleton;
protected $config;
protected $pool;
protected $min = 5;
protected $defaultSize = 100;
protected $max = 1000;
protected $timeout = 0.1;
protected static $links = [];
/**
* MysqlPoolService constructor.
* @throws Exception
*/
protected function __construct()
{
$this->config = Config::getInstance()->getConf('MYSQL-POOL');
if (empty($this->pool)) {
$this->defaultSize = $this->config['master']['pool_max_size'];
$this->min = $this->config['master']['pool_size'];
$this->timeout = $this->config['master']['pool_get_timeout'];
$this->pool = new Channel($this->max);
for ($i = 0; $i < $this->min; $i++) {
$this->add($this->getMysql());
}
\EasySwoole\Component\Timer::getInstance()->loop(5 * 60 * 1000, function (){
// todo 回收过多的老进程
$this->recycle();
});
}
}
/**
* @return MySQL
* @throws Exception
*/
protected function getMysql(): MySQL
{
if(count(self::$links) > $this->max){
throw new Exception('mysql connects too many!');
}
$mysql = new MySQL();
$config = $this->config['master'];
$config['time'] = microtime(true);
$rs = $mysql->connect($config);
if($rs == false){
throw new Exception('mysql connect error!');
}
self::$links[$mysql->sock] = $mysql;
return $mysql;
}
/**
* 回收闲置连接
*/
protected function recycle()
{
while (count(self::$links) > $this->defaultSize){
/**
* @var MySQL $mysql
*/
$mysql = $this->pool->pop($this->timeout);
if($mysql){
$sock = $mysql->sock;
defer(function()use($mysql){
if(!empty($mysql) && $mysql->connected){
$mysql->close();
// echo "recycle-mysql\n";
}
});
unset(self::$links[$sock]);
}
}
}
/**
* 入池
* @param MySQL $mysql
*/
protected function add(MySQL $mysql)
{
$this->pool->push($mysql,$this->timeout);
}
/**
* 获取连接
*
* @return MySQL
* @throws Exception
*/
public function get(): MySQL
{
$length = $this->pool->length();
// 追加到默认值
if($length <= $this->min){
$this->add($this->getMysql());
}
/**
* @var MySQL $mysql
*/
$mysql = $this->pool->pop($this->timeout);
// 超时无法获取连接,追加连接
if(empty($mysql)){
$mysql = $this->getMysql();
$this->add($mysql);
}
// 连接断开,加入新连接
if (empty($mysql->connected)) {
$mysql = $this->getMysql();
}
// 处理结束之后,回收连接
defer(function () use ($mysql) {
$this->add($mysql);
});
return $mysql;
}
}
大概按自己的思路处理了,希望大佬指出不足,以加以完善。