​什么是连接池?

顾名思义,连接池就是一堆预先创建好的连接,跟容器会有点像。连接池主要是在某种需要网络连接的服务,提前把连接建立好存起来,然后存放在一个池子里面,需要用到的时候取出来用,用完之后再还回去。

MySQL连接过程

client 建立连接的认证过程

  • 1、server 监听端口
  • 2、client 向server建立TCP连接
  • 3、server 向client发送挑战码报文(报文详细内容在下文中有分析)
  • 4、client 使用挑战码加密密码,将加密后的密码包含在回包中,发送给server
  • 5、server 根据client的回包,验证密码的有效性,给client发送ok包或error包
  • 6、client发送SQL执行
  • 7、关闭MySQL关闭、TCP连接

为什么使用连接池?

从图可以看到想要执行一条SQL语句每次都要走 图:3.5-1都过程,至少要7步才可以成功。MySQL会有连接数上限的限制,而且每次都执行那么多都步骤,频繁把时间浪费在了网络IO上。

没有连接池的做法类似我们买菜做饭,比如我们要做十个菜,每做一个菜就跑一趟菜市场,挑菜、讨价还价、回家、洗菜、下锅、起锅、洗锅;这样是不是很浪费时间?那我们想要做十个菜,提前把这十个菜的材料都买回来,都洗好备用,然后每次炒都时候直接下锅炒就好了。连接池就是提前买好菜,洗好菜(创建连接、验证账号密码),在要炒菜的时候直接下锅(执行SQL)炒。

使用连接池之后,只有在连接池初始化的时候就进行连接然后存到一个容器里面。每次要执行SQL语句的时候先来这个池获取连接对象,然后再发送SQL语句,当SQL语句执行完之后,再把这个连接归还给连接池。

使用连接池每次执行SQL语句只需要执行 图:3.5-1 的第6步就行了,复用了MySQL连接,在高并发情况下,节省了每次连接带来的其他开销。

连接池有什么?

  • 最小连接数
  • 最大连接数
  • 当前连接数
  • 连接池对象
  • 获取连接池超时时间
  • 健康度检查

实战:Swoole实现连接池

MysqlPool.php

/** * 1、设置配置信息 * 2、创建连接对象 * 3、获取连接对象 * 4、获取连接对象,空闲连接不够创建到最大连接数 * 5、执行sql语句 * 6、归还连接 */use SwooleCoroutineChannel;class MysqlPool{    // 最小连接数    private $min;    // 最大连接数    private $max;    // 当前连接数    private $count = 0;    // 获取超时时间    private $timeOut = 0.2;    // 连接池对象容器    private $connections;    // 配置信息    private $config = [];    // 连接池对象    private static $instance;    public function __construct(array $config){        $this->config = $config;        $this->min = $this->config['min'] ?? 2;        $this->max = $this->config['max'] ?? 4;        $this->timeOut = $this->config['time_out'] ?? 0.2;        $this->connections = new Channel($this->max);    }    /**     * 获取连接池对象     * @param null $config     * @return MysqlPool     */    public static function getInstance($config = null){        if (empty(self::$instance)) {            if (empty($config)) {                throw new RuntimeException("mysql config empty");            }            self::$instance = new static($config);        }        return self::$instance;    }    /**     * 初始化连接池     * @throws Exception     */    public function init(){        for ($i = 0; $i < $this->min; $i++) {            $this->count++;            $mysql = $this->createDb();            $this->connections->push($mysql);        }    }    /**     * 创建数据库连接对象     * @return PDO     * @throws Exception     */    private function createDb(){        $dsn = "mysql:dbname={$this->config['database']};host={$this->config['db_host']}";        try {            $mysql = new PDO($dsn, $this->config['db_user'], $this->config['db_passwd']);            return $mysql;        } catch (PDOException $e) {            throw new Exception($e->getMessage());        }    }    /**     * 获取数据库连接     * @return mixed|null|PDO     * @throws Exception     */    public function getConnection(){        $mysql = null;        // 判断是否为空,如果池空了,判断当前连接数是否下于最大连接数        // 如果小于最大连接数创建新连接数        if ($this->connections->isEmpty()) {            if ($this->count < $this->max) {                $this->count++;                $mysql = $this->createDb();            } else {                $mysql = $this->connections->pop($this->timeOut);            }        } else {            $mysql = $this->connections->pop($this->timeOut);        }        // 获取不到数据库连接抛出异常        if (!$mysql) {            throw new Exception('没有连接了');        }        // 当协程结束之后归还连接池        defer(function () use ($mysql) {            $this->connections->push($mysql);        });        return $mysql;    }    /**     * 调试打印连接池的容量,非主要代码     * @param $str     */    public function printLenth($str){        echo $str . $this->connections->length() . "";    }}

server.php

include './MysqlPool.php';//创建http server$http = new SwooleHttpServer("0.0.0.0", 9501);$http->set(["worker_num" => 2]);$http->on('WorkerStart', function ($serv, $worker_id) {    $config = [        'min' => 3,        'max' => 5,        'time_out' => 1,        'db_host' => '127.0.0.1',        'db_user' => 'root',        'db_passwd' => 'sunny123',        'database' => 'lv'    ];    MysqlPool::getInstance($config)->init();});$http->on('request', function ($request, $response) {    try {        MysqlPool::getInstance()->printLenth(SwooleCoroutine::getCid() . '获取前:');        $mysql = MysqlPool::getInstance()->getConnection();        MysqlPool::getInstance()->printLenth(SwooleCoroutine::getCid() . '归还前:');        $result = $mysql->query("select * from sunny_member");        $row = $result->fetch(MYSQLI_ASSOC);        MysqlPool::getInstance()->printLenth(SwooleCoroutine::getCid() . '归还后:');        $response->end($row['content']);    } catch (Exception $e) {        $response->end($e->getMessage());    }});$http->start();

本案例实现:

  • 最小连接数
  • 最大连接数
  • 当前连接数
  • 连接池对象
  • 获取连接池超时时间

思考:怎么实现健康度检查?

jsp获取连接池的实时连接数_PHP进阶教程-实现一个简单的MySQL连接池相关推荐

  1. mysql多个字符串连接池_使用Coroutine\Channel实现一个简单的MySQL连接池

    Channel通道,类似于go语言的chan,支持多生产者协程和多消费者协程,Swoole底层自动实现了协程的切换和调度 Channel实现原理 通道与PHP的Array类似,仅占用内存,没有其他额外 ...

  2. swoole mysql 连接数_用swoole简单实现MySQL连接池

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

  3. 一个简单的反向连接服务程序

    一个简单的反向连接服务程序 功能简介: 运行后自删除,写注册表Run下,同时自拷贝到系统目录下,注册为系统服务SvrDemo,修改文件时间同Cmd.exe,每隔俩秒钟连接一次本地(127.0.0.1) ...

  4. mysql建立数据浏览器_一个简单的MySQL数据浏览器_php

    这个程序可以用来浏览mysql中的数据,您可以稍做修改就可以做出很不错的MySQL浏览器. */ /* ?cmd=db ?cmd=table&db={} http://www.gaodaima ...

  5. jsp获取连接池的实时连接数_一篇看懂数据库连接池概念、原理、运行机制

    概述 数据库连接池是负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个.那么其中的运行机制又是怎样的呢?今天主要介绍一下数据库连接池原理和常用的连接池. ...

  6. jsp获取连接池的实时连接数_数据库连接池原理分析及模拟实现

    数据库访问 访问数据库主要有以下几个步骤: 加载数据库驱动 创建数据库连接 执行访问操作并处理执行结果 关闭连接,释放资源 在每一次请求数据库都要经历上述过程,创建连接和释放资源也都是些重复性的动作, ...

  7. odbc配置以及一个简单的java连接的代码编写

    1.odbc配置的问题记录 问题描述: 刚开始写好程序之后,直接进行简单数据库调用,但是程序一直报空指针错误,后来查找资料才知道,jdk8里面是没有odbc所用的驱动类,于是换成了jdk7就可以了. ...

  8. python ip动态代理_给自己的爬虫做一个简单的动态代理池

    使用代理服务器一直是爬虫防BAN最有效的手段,但网上的免费代理往往质量很低,大部分代理完全不能使用,剩下能用的代理很多也只有几分钟的寿命,没法直接用到爬虫项目中. 下面简单记录一下我用scrapy+r ...

  9. 一个简单的linux线程池

    线程池:简单地说,线程池 就是预先创建好一批线程,方便.快速地处理收到的业务.比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高. 在linux中,使用的 ...

最新文章

  1. The Memory Managerment of the Computer
  2. 工欲善其事,必先利其器 -- 这烙铁,升温有点狠
  3. ISE中将Verilog封装为IP核的方法
  4. 表格内部的文本对齐类
  5. 1.windows网络配置无法上网
  6. oracle中批量更新,oracle 批量更新
  7. IIS作为ASP.NET Core2.1 反向代理服务器未说的秘密
  8. Visual Studio中使用Git Flow
  9. RabbitMq(八) SpringBoot整合RabbitMQ 生产者代码实现
  10. 移动端开发语言的未来的猜想#华为云·寻找黑马程序员#
  11. oracle统计每天数据增量,每天的业务数据增量导入oracle库方法讨论
  12. 首先定义一个描述银行账户的Account类,包括成员变 量“账号”和“存款余额”,成员方法有“存款”、“取款”和“余额查询”。其次, 编写一个主类,在主类中测试Account类的功能。(已完善)...
  13. QQ2000 的聊天室刷屏机设计技术
  14. 天河二号计算机是微型计算机,计算机二级考试真题-PPT-天河二号超级计算机
  15. VMware Workstation 安装及配置HMC V8R860
  16. 看懂英文数据手册、搭建电路
  17. 为什么web网页会被劫持,网页被劫持的解决方法有哪些?
  18. layui 数字步进器_光音移动设计规范 — 表单类
  19. Restful-API设计最佳实战--Django播客系统(五)
  20. 解决Windows Explorer 奇怪的卡顿问题

热门文章

  1. web服务器(LAMP)通过DNS轮询功能和nfs共享实现负载均衡
  2. 10分钟,快速使用VUE-VUEX
  3. SQL Server里Grouping Sets的威力
  4. 最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surface)
  5. PHPMailer 发送邮件
  6. SlidingMenu(一)
  7. 快速入门cocos2d-x jsbinding
  8. 【探索】Web新概念——资料横向显示(欢迎点评)
  9. (牛人莫入)Silverlight 独立文件存储
  10. secureCRT脚本----vbs语法