闲来无事研究一下 PHP 的 MySQL 持久连接问题。在 mysql 扩展的年代,应该用的是mysql_pconnect,可是那时候我还没有开始接触 PHP, 所以我们直接上 PDO。

首先说一下本次测试用的环境。

imagepng
关键还要看一下 PHP 的配置。

imagepng

注意其中的最重要的参数pm.max_children=1, 这决定了只能有一个 FPM 的 worker 进程来处理所有请求。这样把问题简化更容易发现特征。

我们知道, PHP 的 FPM 有一个 master 进程和若干个 worker 进程, 而 worker 进程并不是像最早的 fastcgi 一样每次处理完一个请求之后就销毁, 下次再来请求需要重新启动。也就是说一个 worker 进程是可以处理多个请求的。这给“持久连接”提供了理论基础。 那么到底它能不能支持持久连接呢?如果支持持久连接, 它的特征又是什么呢?下面直接上代码。

imagepng

我在之前的文章里也提到过 MySQL 的general_log,按这里的描述配置一下就可以很清晰的看到哪个连接在请求服务器了。

反复执行curl http://fpm.org/index.php(我给 fpm.org 配置了 hosts), 就可以看到不断变化的 lastInsertId 了。 但这不是重点, 要看两个现象。

用 root 账户登录 mysql, 执行show processlist;可以看到类似如下的输出:

imagepng

可以看到, 有两个客户端和服务器保持了连接。是谁呢?第一个是 Ubuntu(其实是 Debian)维护的 MySQL 包自带的默认管理员用户, 其实表示的就是当前的这个 MySQL cli 连接。另外一个当然就是刚才调用curl通过 PHP 的 pdo 创建的了。

imagepng

现在再来看 general_log,

imagepng

可以看到多次请求服务器端都是同一个线程 ID(14). 参考这里

那么怎么验证它是由当前这个 FPM 的 worker 维持的呢?很简单, 重启一下 FPM 再看它有没有变化就知道了。

sudo systemctl restart php-fpm.service

imagepng

可以看到一个新的 worker 已经在工作了。 现在重新访问刚才的地址

先再去执行一下show processlist;

imagepng

可以看到 14 已经不在了。因为维持 14 这个连接的 fpm worker 已经挂了,当然对应的服务器的线程也已经销毁了。但 15 出现了。那么这几次请求用的是不是 15 呢?

当然是。

imagepng

所以结论很明显了,在 FPM 模式下是可以使用 mysql 持久化连接的。
所以理论上也可以实现 MySQL 连接池。有时间可以研究一下。 想了想是没有办法实现连接池的, 因为一个 worker 只能维持一个长连接, 无法和别的 worker 共享, 只能通过配置pm.max_children来让 FPM 维持的长连接没有那么多不要超过 MySQL 的最大连接数.

不过这是一个危险操作, 因为你也看到了, 我在写这篇文章的过程中在没有手动重启 FPM 进程之前这个长连接是一直保持的,而如果这个 fpm 进程是空闲的, 那么这个连接就是被浪费的。这有可能导致大量无用的连接占用 MySQL 的连接数, 而连接数是有上限的,超过之后就无法再建立新的连接, 导致后续的连接失败。所以必须设置长连接数的上限, 同时保证 worker 空闲一段时间后退出,(使用pm.max_spare_servers实现)或者再处理若干次请求之后重新启动(通过pm.max_requests实现), 以保证 MySQL 的正常连接数。

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品: PipeSoloSymWide 等,欢迎大家加入,贡献开源。

    3046 引用 • 3713 回帖 • 661 关注
  • FPM
    2 引用 • 2 回帖
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    353 引用 • 385 回帖 • 1149 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 JavaPerl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    103 引用 • 373 回帖 • 661 关注
感谢    赞同    分享    收藏    关注    反对    举报    ...