日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

easyswoole数据库连接池_如何在 Swoole 中优雅的实现 MySQL 连接池

發布時間:2023/12/2 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 easyswoole数据库连接池_如何在 Swoole 中优雅的实现 MySQL 连接池 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如何在 Swoole 中優雅的實現 MySQL 連接池

一、為什么需要連接池 ?

數據庫連接池指的是程序和數據庫之間保持一定數量的連接不斷開,

并且各個請求的連接可以相互復用,

減少重復連接數據庫帶來的資源消耗,

一定程度上提高了程序的并發性能。

二、連接池實現要點

協程:使用 MySQL 協程客戶端。

使用 MySQL 協程客戶端,是為了能在一個 Worker 阻塞的時候,

讓出 CPU 時間片去處理其他的請求,提高整個 Worker 的并發能力。

連接池存儲介質:使用 \swoole\coroutine\channel 通道。

使用 channel 能夠設置等待時間,等待其他的請求釋放連接。

并且在等待期間,同樣也可以讓出 CPU 時間片去處理其他的請求。

假設選擇 array 或 splqueue,無法等待其他的請求釋放連接。

那么在高并發下的場景下,可能會出現連接池為空的現象。

如果連接池為空了,那么 pop 就直接返回 null 了,導致連接不可用。

注:因此不建議選擇 array 或 splqueue。

三、連接池的具體實現

use Swoole\Coroutine\Channel;

use Swoole\Coroutine\MySQL;

class MysqlPool

{

private $min; // 最小連接數

private $max; // 最大連接數

private $count; // 當前連接數

private $connections; // 連接池

protected $freeTime; // 用于空閑連接回收判斷

public static $instance;

/**

* MysqlPool constructor.

*/

public function __construct()

{

$this->min = 10;

$this->max = 100;

$this->freeTime = 10 * 3600;

$this->connections = new Channel($this->max + 1);

}

/**

* @return MysqlPool

*/

public static function getInstance()

{

if (is_null(self::$instance)) {

self::$instance = new self();

}

return self::$instance;

}

/**

* 創建連接

* @return MySQL

*/

protected function createConnection()

{

$conn = new MySQL();

$conn->connect([

'host' => 'mysql',

'port' => '3306',

'user' => 'root',

'password' => 'root',

'database' => 'fastadmin',

'timeout' => 5

]);

return $conn;

}

/**

* 創建連接對象

* @return array|null

*/

protected function createConnObject()

{

$conn = $this->createConnection();

return $conn ? ['last_used_time' => time(), 'conn' => $conn] : null;

}

/**

* 初始化連接

* @return $this

*/

public function init()

{

for ($i = 0; $i < $this->min; $i++) {

$obj = $this->createConnObject();

$this->count++;

$this->connections->push($obj);

}

return $this;

}

/**

* 獲取連接

* @param int $timeout

* @return mixed

*/

public function getConn($timeout = 3)

{

if ($this->connections->isEmpty()) {

if ($this->count < $this->max) {

$this->count++;

$obj = $this->createConnObject();

} else {

$obj = $this->connections->pop($timeout);

}

} else {

$obj = $this->connections->pop($timeout);

}

return $obj['conn']->connected ? $obj['conn'] : $this->getConn();

}

/**

* 回收連接

* @param $conn

*/

public function recycle($conn)

{

if ($conn->connected) {

$this->connections->push(['last_used_time' => time(), 'conn' => $conn]);

}

}

/**

* 回收空閑連接

*/

public function recycleFreeConnection()

{

// 每 2 分鐘檢測一下空閑連接

swoole_timer_tick(2 * 60 * 1000, function () {

if ($this->connections->length() < intval($this->max * 0.5)) {

// 請求連接數還比較多,暫時不回收空閑連接

return;

}

while (true) {

if ($this->connections->isEmpty()) {

break;

}

$connObj = $this->connections->pop(0.001);

$nowTime = time();

$lastUsedTime = $connObj['last_used_time'];

// 當前連接數大于最小的連接數,并且回收掉空閑的連接

if ($this->count > $this->min && ($nowTime - $lastUsedTime > $this->freeTime)) {

$connObj['conn']->close();

$this->count--;

} else {

$this->connections->push($connObj);

}

}

});

}

}

$httpServer = new swoole_http_server('127.0.0.1',9501);

$httpServer->set(['work_num' => 1]);

$httpServer->on('WorkerStart', function ($request, $response) {

MysqlPool::getInstance()->init()->recycleFreeConnection();

});

$httpServer->on('Request', function ($request, $response){

$conn = MysqlPool::getInstance()->getConn();

$conn->query('SELECT * FROM fa_admin WHERE id=1');

MysqlPool::getInstance()->recycle($conn);

});

$httpServer->start();

四、總結

定時維護空閑連接到最小值。

使用用完數據庫連接之后,需要手動回收連接到連接池。

使用 channel 作為連接池的存儲介質。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的easyswoole数据库连接池_如何在 Swoole 中优雅的实现 MySQL 连接池的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。