PHP-FPM + nginx - 池繁忙并针对可能糟糕的 PHP 代码进行优化 - 502 错误

PHP-FPM + nginx - 池繁忙并针对可能糟糕的 PHP 代码进行优化 - 502 错误

我曾经遇到过这样的情况:即使流量稍微增加,PHP-FPM 也无法正常工作。一段时间以来,我一直在尝试寻找实际原因,但至今没有成功。

它始于特定站点给出 502 错误,查看 PHP-fpm 日志我得到了以下信息:

WARNING: [pool www-userA] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 39 idle, and 49 total children

接下来我检查了服务器资源,top 显示资源利用率几乎为 0,仅为 2-4%。接下来是调整 PHP-FPM 池:

pm = dynamic
pm.max_children = 800
pm.process_idle_timeout = 5s
pm.start_servers = 40
pm.min_spare_servers = 40
pm.max_spare_servers = 80
pm.max_requests = 500
php_admin_value[max_execution_time] = 60

;Added later to troubleshoot further
request_slowlog_timeout = 5s
slowlog = /var/log/pool_userA_fpm_slow_log

;Added later to compensate if there queue issue for troubleshooting
listen.backlog =24000

我几乎读过所有与此主题相关的 PHP-FPM 帖子,其中包括: https://stackoverflow.com/questions/25097179/warning-pool-www-seems-busy-you-may-need-to-increase-pm-start-servers-or-pm

该服务器仅配备 12GB 左右的 RAM 和 8 核处理器,用于 nginx+php-fpm。我的每个 PHP 进程大约为 15-20MB。

尝试增加pm.max_children = 1500但过了一会儿又看到同样的错误“池很忙”。

然后,我在 php-fpm 中启用了 slowlog,并为 mysql 启用了 slow log。

  • 在 php-fpm 慢速日志中,我发现一些 php 页面需要大约 5 秒才能完成,
  • 在 mysql 慢日志中,发现一些查询检查了 200-500 万行(大约需要 5 秒才能完成)

假设 PHP 脚本可能会导致排队或积压,因此我listen.backlog =24000 在 /etc/security/limits.conf 中为该特定用户添加了软限制和硬限制,以便为慢速脚本提供空间,

userA    soft    nofile    4096
userA    hard    nofile    65536

进一步在 sysctl 中。

echo "net.core.somaxconn=65536" >> /etc/sysctl.conf

进一步在 php-fpm master php-fpm.conf 中添加,即外部池配置:

rlimit_files = 65536
rlimit_core = 0

我的ulimit -Hn说:

524288

此外,由于 php-fpm 变得繁忙,我发现我可以在 php-fpm 中添加以下指令,以便在繁忙时重新启动,但这并没有发生,我必须手动重新启动 php-fpm 才能让网站再次运行:

[global]
emergency_restart_threshold 10
emergency_restart_interval 1m
process_control_timeout 10s

如上所述,如果 php-fpm.log 中出现池繁忙错误,上述指令不会重新启动

到目前为止,我猜测是因为 PHP 脚本太慢,导致我的 php-fpm 子进程耗尽并导致 502 错误。我无法控制 PHP,因此需要通过调整服务器配置来提供解决方案。

我尝试增加pm.max_children = 2000,但问题仍然存在。有时会出现504 Gateway Time-out错误。

另一方面,如果我changed pm = ondemand

我首先收到以下通知:

 listen.backlog(25000) was too low for the ondemand process manager. I updated it for you to 65535

后来又出现这个错误,这次又出现 504 错误:

[11-Nov-2021 06:56:45] WARNING: [pool userA] server reached max_children setting (800), consider raising it.

需要注意的是,在所有情况下,服务器几乎没有负载,资源使用率为 2-4%。所以我猜这更多的是配置问题,而不是资源使用问题。

我浏览了 serverfault 上几乎所有与 PHP-FPM 相关的主题,也阅读了大量文档,但仍然一无所获。希望有人能为我指明正确的方向。

谢谢

相关内容