swoole-framwork/core/lib/DBPool.php

130 lines
3.3 KiB
PHP
Raw Permalink Normal View History

2024-05-21 14:33:56 +08:00
<?php
namespace Core\lib;
abstract class DBPool
{
private $min;
private $max;
private $conns;
private $count;
private $idleTime = 40;
abstract protected function newDB();
function __construct($min = 5, $max = 10)
{
$this->min = $min;
$this->max = $max;
$this->conns = new \Swoole\Coroutine\Channel($this->max);
for ($i = 0; $i < $min; $i++) {
$this->addDBToPool();
}
2024-06-26 17:13:45 +08:00
\Swoole\Timer::tick(30000, [$this, 'keepAlive']);
//\Swoole\Timer::tick(30000, [$this, 'keepAlive']);
}
public function keepAlive()
{
for ($i = 0; $i < $this->conns->length(); $i++) {
$dbObj = $this->getConnection();
try {
$res = $dbObj->db->query('select 1');
//var_dump($res);
$this->close($dbObj);
}catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
2024-05-21 14:33:56 +08:00
}
public function initPool()
{
/*for ($i = 0; $i < $this->min; $i++) {
$db = $this->newDB();
$this->conns->push($db);
}
$this->count = $this->min;*/
}
public function getConnection()
{
if($this->conns->isEmpty()){
if ($this->count < $this->max) {
$this->addDBToPool();
$dbObject = $this->conns->pop();
}else{
$dbObject = $this->conns->pop(5);
}
}else{
$dbObject = $this->conns->pop();
}
if ($dbObject) {
$dbObject->usedTime = time();
}
2024-06-26 17:13:45 +08:00
/**$res = $this->pdoPing($dbObject->db);
2024-05-22 14:49:06 +08:00
if (!$res) {
$this->count--;
$this->addDBToPool();
return $this->getConnection();
2024-06-26 17:13:45 +08:00
}*/
2024-05-21 14:33:56 +08:00
return $dbObject;
}
2024-05-22 14:49:06 +08:00
function pdoPing($dbconn){
try{
$dbconn->getAttribute(\PDO::ATTR_SERVER_INFO);
} catch (\Exception $e) {
/*if(strpos($e->getMessage(), 'MySQL server has gone away')!==false){
return false;
}*/
return false;
}
return true;
}
2024-05-21 14:33:56 +08:00
public function close($conn)
{
if ($conn) {
$this->conns->push($conn);
}
}
public function addDBToPool()
{
try {
$this->count++;
$db = $this->newDB();
if (!$db) throw new \Exception('db创建错误');
$dbObject = new \stdClass();
$dbObject->usedTime = time();
$dbObject->db = $db;
$this->conns->push($dbObject);
}catch (\Exception $e) {
$this->count--;
}
}
public function cleanPool()
{
2024-05-22 14:49:06 +08:00
if ($this->conns->length() < $this->min && $this->conns->length()<intval($this->max * 0.6)) {
2024-05-21 14:33:56 +08:00
return ;
}
$dbbak = [];
while (true) {
if($this->conns->isEmpty()) {
break;
}
$obj = $this->conns->pop(0.1);
if($this->count > $this->min && (time()-$obj->usedTime) > $this->idleTime){
$this->count--;
} else{
$dbbak[] = $obj;
}
}
foreach ($dbbak as $db){
$this->conns->push($db);
}
}
}