PHP FPM 循环导致巨大的 RAM 消耗

PHP FPM 循环导致巨大的 RAM 消耗

几个 ubuntu 服务器,使用 php8.0 / php8.1,以 NGINX 作为网络服务器,导致了这个问题,我的内存正在填满 - 基于传入流量(req/s),所以我必须每 30 分钟重新启动一次 fpm 进程,因为否则 FPM 会变得非常慢并且传入的请求开始排队。

由于我有几台服务器,我尝试在所有服务器上对 PM 进行不同的设置,以检查问题是否不会发生。因此,我尝试使用静态/动态/按需 > 的 PM,大约一小时后,它们都非常慢。我还尝试对它们使用 max_request,让它们自动循环,而不是让它们永远存在 - 没有任何成功。

没有段错误,我正在使用 apcu 和 opcache 作为扩展,尝试关闭 apcu,但无论如何 RAM 都在堆积 - 直到 FPM 变慢。我发现每次 fpm 重新启动都会导致大量小页面错误(300k),并且在通常的运行时最多为 40-80k >,当达到 100k 时,它开始变慢。

此外,即使没有 apcu,共享内存也会堆积,因此我认为每个常规循环(不是 fpm 重启)都会导致共享内存出现问题。我也没有看到任何关于尝试分配过多 RAM 或以任何方式超出 RAM 的错误。

很高兴我能核实任何想法。

编辑:如果我可以提供任何进一步的信息,请随时告诉我

编辑2:安装了ps_mem,发现只有共享内存随着时间的推移而增加,而不是子进程本身声明/定义的内存。

编辑 3:当前设置之一基本上是这样的:

listen = /run/php/php8.1-main-fpm.sock
;listen.backlog = 8000 
listen.backlog = -1
listen.owner = www
listen.group = www-data
listen.mode = 0660

user = www
group = www

slowlog = /var/log/slow-php8.1-fpm.log
request_slowlog_timeout = 2s

pm = static
pm.max_children = 700
pm.max_requests = 0
request_terminate_timeout = 7s
pm.status_path = /status

我也尝试通过 ps_mem 来解决这个问题。重启后,输出如下:

$ ps_mem  | grep php
2.2 GiB + 112.2 MiB =   2.3 GiB php-fpm8.1 (903)

两分钟后:

$ ps_mem  | grep php
2.3 GiB + 164.4 MiB =   2.4 GiB php-fpm8.1 (903)

十五分钟后:

$ ps_mem  | grep php
2.5 GiB + 272.6 MiB =   2.8 GiB php-fpm8.1 (903)

该服务器有 64 个 CPU 和大约 128 GB 的 Ram。

编辑 3:刚刚有一个很好的发现,这影响了当前的问题 - 每分钟执行此命令有助于解决问题

sync; echo 1 > /proc/sys/vm/drop_caches

这是一个临时的解决方案——想发现问题的根源。

答案1

根据您的特定应用程序,单个页面请求可能需要一个 PHP-FPM 工作器,且最低 RAM 仅大约为 80MB。

将其乘以你的配置pm.max_children = 700,你会发现,随着许多请求进入并使所有工作人员忙碌,你会得到至少使用了 56GB。这是当您的应用非常精简时的情况。每个请求很容易占用 100MB 或 120MB,等等。

这只pm.max_requests = 0会让情况变得更糟。PHP 工作进程中总是存在内存泄漏和错误。你必须将其设置为某个值,以便回收工作者。否则,工作者将在 RAM 中无限增长,直到您重新启动 PHP-FPM 并清除流量。将其设置为100010000(在请求数达到该值后,工作者将被回收),但绝不能设置为0

最后,不要这样做request_slowlog_timeout = 2s。慢速日志记录不适合生产环境。(不过暂时没问题)。

相关内容