谈谈 PHP-FPM 模式下的 MySQL 持久连接

本贴最后更新于 2239 天前,其中的信息可能已经天翻地覆

闲来无事研究一下 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 已经开源了多款产品:SymSoloVditor思源笔记

    1083 引用 • 3461 回帖 • 262 关注
  • FPM
    2 引用 • 2 回帖
  • MySQL

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

    675 引用 • 535 回帖
  • PHP

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

    165 引用 • 407 回帖 • 514 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 52 关注
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 247 回帖 • 148 关注
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    493 引用 • 1385 回帖 • 342 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    170 引用 • 414 回帖 • 405 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 531 关注
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    334 引用 • 323 回帖 • 25 关注
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 683 关注
  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 232 回帖
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    124 引用 • 580 回帖
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 614 关注
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 5 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 1 关注
  • 安装

    你若安好,便是晴天。

    131 引用 • 1184 回帖 • 1 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 21 关注
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    379 引用 • 1221 回帖 • 588 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 1 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 50 关注
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    23 引用 • 31 回帖 • 8 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    541 引用 • 3529 回帖
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 611 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 383 回帖 • 4 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    324 引用 • 1395 回帖 • 4 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    21 引用 • 37 回帖 • 519 关注
  • 分享

    有什么新发现就分享给大家吧!

    244 引用 • 1762 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 582 关注