使用 Nginx + PHP-FPM 的 WordPress 有时会很慢,其中 slowlog 指向 wp-config.php (PHP 8.1)

使用 Nginx + PHP-FPM 的 WordPress 有时会很慢,其中 slowlog 指向 wp-config.php (PHP 8.1)

我最近安装了 WordPress 6,并在 Docker 上运行了 MariaDB 和 PHP 8 FPM。有时,前端的请求在主 HTML 文档上的响应时间很慢。在此示例中,其中一个类别页面花费了 1.8 秒:

在此处输入图片描述

由于所有查询仅花费 0.06 秒,并且根据插件,我们没有外部 HTTP 调用,因此我无法解释为什么会发生这种情况。通常我们有 ~300-400ms,这仍然有点高,但比 ~1.8s 更容易接受。

PHP FPM 的 slowlog 跟踪仅显示

php    | [30-Jul-2022 10:50:46] WARNING: [pool www] child 26, script '/www/index.php' (request: "GET /wp/index.php?category/software/") executing too slow (1.170804 sec), logging
php    | [30-Jul-2022 10:50:46] NOTICE: child 26 stopped for tracing
php    | [30-Jul-2022 10:50:46] NOTICE: about to trace 26
php    | [30-Jul-2022 10:50:46]  [pool www] pid 26
php    | script_filename = /www/index.php
php    | [0x00007f86db6129c0] [INCLUDE_OR_EVAL]() /www/wp-config.php:110
php    | [0x00007f86db612720] [INCLUDE_OR_EVAL]() /www/wp-load.php:50
php    | [0x00007f86db612190] [INCLUDE_OR_EVAL]() /www/wp-blog-header.php:13
php    | [0x00007f86db612090] [INCLUDE_OR_EVAL]() /www/index.php:17
php    | [30-Jul-2022 10:50:46] NOTICE: finished trace of 26

这对我来说似乎没什么用,因为这行wp-config.php只包含

110 require_once(ABSPATH . 'wp-settings.php');

并且wp-settings.php它本身是一个非常大的脚本,包括大量其他 php 文件。因此,我找不到任何方法来分析导致这种大规模减速的原因。

我的 PHP-FPM 配置

log_level = notice
error_log = /proc/self/fd/2


[www]
; if we send this to /proc/self/fd/1, it never appears
access.log = /proc/self/fd/2
;access.log = /dev/null

clear_env = no

user = www-data
group = www-data
listen = 127.0.0.1:9000

;pm = dynamic
;pm.max_children = 40
;pm.start_servers = 20
;pm.min_spare_servers = 10
;pm.max_spare_servers = 25
;pm.max_requests = 200

pm = static
pm.max_children = 40
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 20
pm.max_requests = 100
; https://www.kevinhooke.com/2018/02/27/nginx-php5-fpm-response-lag-on-first-requests/
pm.process_idle_timeout = 10s
pm.status_path = /status

slowlog = /proc/self/fd/2
request_slowlog_timeout = 1s

catch_workers_output = yes
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

由于这是一个测试环境,因此没有外部流量。我也在 PHP-FPM 状态页面上验证了这一点,其中大多数工作程序处于空闲状态。有时页面加载速度甚至更慢(最多 8 秒),这取决于时间,这看起来像是负载问题,但事实并非如此。即使是运行这些容器的裸机服务器,负载也很低:

Load average: 0.38 0.60 0.59

编辑

我注意到,当我重新启动 Nginx + PHP-FPM(两者都在单个 Compose 文件中,MariaDB 在单独的文件中)时,页面加载时间要快得多。但这并不能永久解决问题,一段时间后它又变慢了。我已经尝试减少pm.max_requests = 100,之前是 500,但没有解决问题。

答案1

我发现我犯了一个愚蠢的错误:由于这是一个测试环境,我将 PHP 容器的内存限制减少到docker-compose.yml1 GB

services:
  test-php:
    # ...
    mem_limit: 1G

之前设置为 2 GB,因为在生产安装中,平均脚本内存消耗 * 子进程将计算为 1.7 GB。我在测试环境中忘记了这一点,因此发生了以下情况:PHP 生成多个进程并且不释放内存。这会在一些请求之后填满容器内存,从而导致页面加载时间变慢。

这非常令人困惑,因为过了一段时间,我还在日志中看到了 MySQLi 错误,这让我去查看数据库,结果却被误导了。这只是对数据库的调用,或者发布的日志条目中的配置,其中容器的内存是满的已到达极限。

相关内容