实现一个协程版的mysql连接池,该连接池支持自动创建最小连接数,自动检测mysql健康;基于swoole的chanel。

最近事情忙,心态也有点不积极。技术倒是没有落下,只是越来越不想写博客了。想到平时自己上网上找资料的痛苦,于是将自己这篇连接池的文章放出来,给需要的程序员一点帮助。

<?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();
});

实现一个协程版mysql连接池的更多相关文章

  1. nodejs + redis/mysql 连接池问题

    nodejs + redis/mysql 连接池问题 需不需要连接池 连接池的作用主要是较少每次临时建立连接所带来的开销.初步一看,nodejs运行单线程上,它不能同时使用多个连接,乍一看是不需要连接 ...

  2. Swoole MySQL 连接池的实现

    目录 概述 代码 扩展 小结 概述 这是关于 Swoole 入门学习的第八篇文章:Swoole MySQL 连接池的实现. 第七篇:Swoole RPC 的实现 第六篇:Swoole 整合成一个小框架 ...

  3. 如何在 Swoole 中优雅的实现 MySQL 连接池

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

  4. 解决Mysql连接池被关闭 ,hibernate尝试连接不能连接的问题。 (默认mysql连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池。系统发布第二天访问链接关闭问题。

    解决Mysql连接池被关闭  ,hibernate尝试连接不能连接的问题. (默认MySQL连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池. 所以系统发布第二天访问会 ...

  5. Java Mysql连接池配置和案例分析--超时异常和处理

    前言: 最近在开发服务的时候, 发现服务只要一段时间不用, 下次首次访问总是失败. 该问题影响虽不大, 但终究影响用户体验. 观察日志后发现, mysql连接因长时间空闲而被关闭, 使用时没有死链检测 ...

  6. MySQL连接池

    1. using System; using System.Collections; using MySql.Data.MySqlClient; namespace Helper { /// < ...

  7. tomcat中使用mysql连接池的配置

    1.下载相应的jar包,添加到工程中 需要下载的包主要有commons-pool2-2.2 commons-dbcp2-2.0.1-src commons-dbcp2-2.0.1  commons-c ...

  8. mysql连接池的使用工具类代码示例

    mysql连接池代码工具示例(scala): import java.sql.{Connection,PreparedStatement,ResultSet} import org.apache.co ...

  9. 用swoole简单实现MySQL连接池

    MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...

随机推荐

  1. MySQL和Mariadb二进制日志binlog详解

    Mariadb/mysql提供了4中不同的日志,分别是错误日志(error.log).普通日志(general log).慢日志(slow log)以及二进制日志(binlog).错误日志记录了系统启 ...

  2. 第一次项目上Linux服务器(八:——搭建Nginx图片服务器)

    一.准备工作 安装Nginx,参考历史博客 二.搭建Nginx图片服务器 1.效果 例如:图片通过xftp服务上传到/home/java/upload目录下,我想通过访问Nginx服务器来访问xftp ...

  3. UVa 10129 Play on Words(并查集+欧拉路径)

    题目链接: https://cn.vjudge.net/problem/UVA-10129 Some of the secret doors contain a very interesting wo ...

  4. 手把手教你实现自己的abp代码生成器

    代码生成器的原理无非就是得到字段相关信息(字段名,字段类型,字段注释等),然后根据模板,其实就是字符串的拼接与替换生成相应代码. 所以第一步我们需要解决如何得到字段的相关信息,有两种方式 通过反射获得 ...

  5. mysql 创建数据库,添加用户,用户授权

    一.创建mysql数据库 1.创建数据库语法 --创建名称为"testdb"数据库,并设定编码集为utf8 CREATE DATABASE IF NOT EXISTS testdb ...

  6. Android获取SD卡总容量,可用大小,机身内存总容量及可用大小

    public long getSDTotalSize() { /*获取存储卡路径*/ File sdcardDir= Environment.getExternalStorageDirectory() ...

  7. [android] 手机卫士号码归属地查询

    使用小米号码归属地数据库,有两张表data1和data2 先查询data1表,把手机号码截取前7位 select outkey from data1 where id=”前七位手机号” 再查询data ...

  8. 前m大的数(hdu1280)

    前m大的数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  9. Singleton(单例)模式和Double-Checked Locking(双重检查锁定)模式

    问题描述 现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能:在实际开发过程中,会专门有一个日志模块,负责写日志,由于在系统的任何地方,我们都有可能要调用日志模块中的函数,进 ...

  10. jqgrid 获取当前页数据

    /** *刷新,jqGrid刷新当前列表页代码 */ function refresh(url) { var page = $('#your_grid').getGridParam('page'); ...