一、为什么需要连接池 ?

数据库连接池指的是程序和数据库之间保持一定数量的连接不断开,

并且各个请求的连接可以相互复用,

减少重复连接数据库带来的资源消耗,

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

二、连接池实现要点协程:使用 MySQL 协程客户端。

使用 MySQL 协程客户端,是为了能在一个 Worker 阻塞的时候,

让出 CPU 时间片去处理其他的请求,提高整个 Worker 的并发能力。连接池存储介质:使用 \swoole\coroutine\channel 通道。

使用 channel 能够设置等待时间,等待其他的请求释放连接。

并且在等待期间,同样也可以让出 CPU 时间片去处理其他的请求。

假设选择 array 或 splqueue,无法等待其他的请求释放连接。

那么在高并发下的场景下,可能会出现连接池为空的现象。

如果连接池为空了,那么 pop 就直接返回 null 了,导致连接不可用。

注:因此不建议选择 array 或 splqueue。

三、连接池的具体实现

useSwoole\Coroutine\Channel;

useSwoole\Coroutine\MySQL;

classMysqlPool

{ private$min;// 最小连接数

private$max;// 最大连接数

private$count;// 当前连接数

private$connections;// 连接池

protected$freeTime;// 用于空闲连接回收判断

publicstatic$instance;

/**

* MysqlPool constructor.

*/

publicfunction__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 作为连接池的存储介质。

如果你喜欢我写的技术文章以及面试总结,欢迎关注收看我的视频,并且点赞、收藏、关注我哦。

我是luke,感谢你的关注!

很多小伙伴在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,希望能够去帮助到小伙伴们,可以关注我。并且加入到我的圈子一起学习成长哦【架构师之路】点击链接申请加入圈子架构师之路 - 知乎​www.zhihu.com

swoole 连接mysql_Swoole 优雅的实现 MySQL 连接池相关推荐

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

    如何在 Swoole 中优雅的实现 MySQL 连接池 一.为什么需要连接池 ? 数据库连接池指的是程序和数据库之间保持一定数量的连接不断开, 并且各个请求的连接可以相互复用, 减少重复连接数据库带来 ...

  2. MySQL连接问题【如何解决MySQL连接超时关闭】

    --MySQL连接问题[如何解决MySQL连接超时关闭] ------------------------------------------------转载 最近做网站有一个站要用到WEB网页采集器 ...

  3. mysql内连接和外连接的区别_Swoole4创建Mysql连接池

    一 .什么是mysql连接池 场景:每秒同时有1000个并发,但是这个mysql同时只能处理400个连接,mysql会宕机. 解决方案:连接池,这个连接池建立了200个和mysql的连接,这1000个 ...

  4. MySQL会回收使用中的连接吗_Node.js实现mysql连接池使用事务自动回收连接的方法示例...

    本文实例讲述了Node.js实现mysql连接池使用事务自动回收连接的方法.分享给大家供大家参考,具体如下: var mysql = require('mysql'), Connection = re ...

  5. mysql错误连接次数过多_解决Mysql连接过多错误的方法

    问:怎样解决mysql连接过多的错误? 答:系统不能连接数据库,关键要看两个数据: 1.数据库系统允许的最大可连接数max_connections.这个参数是可以设置的.如果不设置,默认是100.最大 ...

  6. mysql 连接 指定字符集_关于Mysql连接池配置指定字符集的问题

    问题是这样的,我在写一个网站,打算使用连接池.我使用J2EE开发,开始使用的是直连的方式,附上代码public class ConnDb { private String getDriver = &q ...

  7. mysql关闭空闲连接_终止空闲的mysql连接

    手动清理: 你可以杀死进程. mysql> show full processlist; +---------+------------+-------------------+------+- ...

  8. c语言 socket 断开自动连接,如何优雅地断开TCP连接?

    socket关闭: close()和shutdown()的差异 对于一个tcp连接,在c语言里一般有2种方法可以将其关闭: close(sock_fd); 或者 shutdown(sock_fd, . ...

  9. idea怎么和mysql连接并执行_IDEA 与MySQL连接问题

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 java.sql.SQLNonTransientConnectionException: Could not create connection to d ...

  10. mysql 连接字符串 c#_C#版mysql连接字符串

    第一种方式.ODBC DSN 1.   // ODBC DSN 2. 3.   using System.Data.Odbc; 4. 5.   OdbcConnection conn = new Od ...

最新文章

  1. tf.squeeze示例代码
  2. Reddit欲融资3亿美元,由腾讯领投
  3. ByteArrayOutputStream用法
  4. android 布局管理器,【Android开发】布局管理器-表格布局
  5. 浅谈相对定位与绝对定位
  6. php调用mysql中文变量_用php调用MySQL里的数据,为什么汉字都变成了问号?在线等...
  7. 基于FTP4J组件的FTP操作客户端
  8. java 堆栈大小设置_如何增加Java堆栈大小?
  9. 程序员的思维修炼--读书感悟
  10. 【1】国产USB转接芯片CH347-初体验
  11. 申请阿里云香港试用1年服务器教程
  12. 家庭养花的资料大全-春雷转
  13. 自走棋java代码,【自走棋】地图格子高亮效果
  14. Maven --- 简介
  15. 5G uRLLC技术及其与TSN的融合
  16. 用Java做的模拟“双色球”机选号码
  17. Vista Beta下载
  18. python高校教务管理系统
  19. LinkedIn 国际版怎么在国内登录?怎么使用领英国际版?
  20. 关于10进制的一些换算

热门文章

  1. mysql 自动复制_MySQL复制 自动监控脚本-阿里云开发者社区
  2. C#使用NPIO读写excle,并生成多个表单
  3. 关于IIS中Request.ServerVariables(SCRIPT_NAME)的bug
  4. SVM 超平面方程
  5. LAMP(Linux+Apachd+Mysql+Php)搭建网站环境
  6. ERP选型需把握主动权!
  7. 差分形式的阻滞增长模型matlab,差分形式的阻滞增长模型.ppt
  8. 木门怎么打_装门框,只打发泡剂一点不牢固!如今门套下沉,气得邻居直跺脚!...
  9. java找链表中最小值_算法图解:如何找出栈中的最小值?
  10. 文本文件与二进制的区别