Wanzul Blog

Notes, opinions, and lessons I paid for.

How Many Database Does a Site Open? ( &# ; Analysis)

一个 WordPress 网站会开启多少个数据库连接?(实验 & 分析)

你是否想过,一个 WordPress 请求实际上会打开多少个数据库连接?了解这一点对于扩展网站以及避免可怕的 “Error establishing a database connection.” 错误至关重要。在本文中,我们会深入探讨影响这些连接的因素,并进行一项实时实验来验证结果。

影响连接数量的因素

  1. 服务器数量: 典型的 WordPress 安装都托管在单一服务器上。然而,在使用负载均衡器的高可用性设置中,多台服务器会同时与数据库交互。
  2. WordPress 插件: 编写良好的插件应使用 WordPress 提供的全局 $wpdb 对象,该对象会复用现有连接。编写不佳的插件可能会创建新的独立连接,导致每个请求产生不止一个数据库连接。
  3. 活动请求: 数据库连接只在请求处理期间保持打开。如果某一刻你的网站没有访客,就不会有活动的数据库连接。
  4. 服务器配置: PHP 接口类型(例如 PHP-FPM 或 mod_php)会影响连接的管理和池化方式。

效率提示:优化不佳的插件是数据库连接过多的常见原因。


实验 🔬

在本节中,我们将验证默认的 WordPress 安装是否真的每个请求只消耗一个数据库连接。


1/5:如何监控活动数据库连接

虽然你可以使用 MySQL Workbench 等数据库工具,也可以使用一个简单的 PHP 脚本查询 information_schema.processlist 表,以实时查看活动连接。

关键逻辑: 以下脚本会连接数据库,并按用户对活动进程进行分组,让我们可以隔离出 WordPress 应用用户所建立的连接。

<?php
// Database credentials
$servername = "mysql";
$username = "root";
$password = "password";

// Create connection
$conn = new mysqli($servername, $username, $password);

// Check connection
if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}

// Query to get the number of threads connected based on user
$sql = "SELECT user, COUNT(*) as connections FROM information_schema.processlist GROUP BY user";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
  while ($row = $result->fetch_assoc()) {
    // Filter for your specific WordPress database user
    if ($row['user'] == 'site_11703') {
      echo "User: " . $row["user"] . " - Connections: " . $row["connections"] . "<br>";
    }
  }
}
Output of the connection count script showing active database threads
示例脚本输出,显示 WordPress 用户的活动连接。

注意:确保数据库用户具有访问 information_schema 表所需的权限。


2/5:模拟长时间运行的请求

由于全新的 WordPress 安装加载速度极快,在监控工具中很难捕捉到活动连接。为了让它可见,我们会故意放慢执行速度。

通过在 wp-settings.php 文件末尾添加 sleep(10) 命令,WordPress 会在完成请求前将数据库连接保持打开 10 秒。

Code snippet showing sleep(10) added to wp-settings.php
为测试目的,在 wp-settings.php 末尾添加 sleep(10)。

3/5:演示 -> 对 WordPress 网站发出单个(1)请求

现在,我们向网站发出一个请求,并在监控脚本中检查连接数。

验证:单个 WordPress 请求正好消耗 1 个数据库连接。

4/5:演示 -> 并发请求(5 个请求)

为了模拟并发请求,我们不能只使用多个浏览器标签页,因为 HTTP/2 多路复用 可能会将它们合并成一个连接。相反,我们使用 k6 负载测试工具同时发出 5 个独立请求。

证明:5 个并发请求会产生 5 个活动的数据库连接。

5/5:演示 -> 达到容量上限(10 个请求)

这个测试案例突出了一个关键的服务器瓶颈:PHP-FPM worker 进程池上限。

PHP-FPM pool configuration showing pm.max_children set to 5
我们的测试环境将 pm.max_children 设置为 5。

由于只有 5 个 PHP worker 进程可用,服务器一次只能处理 5 个 WordPress 请求。即使我们发出 10 个请求,数据库连接数仍会保持在 5,因为其余请求会被 Web 服务器排队。

观察结果:数据库连接数受活动 PHP worker 数量的限制。

结论

默认情况下,WordPress 在其执行期间只会打开一个数据库连接。请求完成后,连接会被关闭并返回连接池。

扩展网站时,请记住,垂直扩展(增加 PHP worker)和水平扩展(增加服务器)都会增加同时数据库连接的总数。始终确保你的数据库 max_connections 设置足够高,以容纳最大可能的 PHP worker 数量,从而避免服务中断。

Wan Zulkarnain 的头像

Written by 

Comments

发表回复