![PHP 脚本在 Apache 上突然加载非常慢](https://linux22.com/image/770987/PHP%20%E8%84%9A%E6%9C%AC%E5%9C%A8%20Apache%20%E4%B8%8A%E7%AA%81%E7%84%B6%E5%8A%A0%E8%BD%BD%E9%9D%9E%E5%B8%B8%E6%85%A2.png)
我正在使用 mpm_event 测试为什么我的 PHP 脚本有时需要很长时间才能通过网络加载(>30 秒),该服务器使用 PHP-FPM 7.4。过去几个月,服务器运行正常,几天前开始出现这种情况,我没有做任何更改。我重启了,但没有帮助。
我做了一个简单的test.php
。有时它可以正常加载(<100ms),但有时需要1分钟才能加载:
<?php echo "test\n"; ?>
- 服务器的 CPU、RAM 和 IO 均正常(用 检查
htop
)。 - 静态 HTML 文件加载无任何延迟。
- 通过 SSH 控制台本地运行脚本非常快。
- Apache 错误日志没有显示任何异常。
- 我通过检查来自相同 /16 子网的连接 IP 数量来检查是否存在某些 DDOS 攻击,并没有发现任何异常(例如 >100 个连接)。
我该如何进一步调试以了解发生这种情况的原因?
一些可能有帮助的调试输出:
sudo service php7.4-fpm status
答案1
我想我已经找到了解决方案,但如果您仍然有任何建议,请告诉我或发布其他答案。
我检查了一下/var/log/php7.4-fpm.log
,发现有很多这样的条目:
[2021-09-30 03:36:46] 警告:[pool www] 服务器已达到 pm.max_children 设置 (5),请考虑提高该值
所以我上调到max_children
15 似乎有帮助。
答案2
造成这种现象的原因可能有多种:
- 如果该Web服务器处理来自外部网络的请求,那么随着流量的增加,负载可能会增加,从而导致服务器响应时间增加。
- 如果您的脚本使用了对外部资源的调用,那么在这种情况下,由于外部资源的响应速度较慢,您的服务器的响应时间可能会增加。
日志消息:
[30-Sep-2021 03:36:46] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
只是负荷增加的证明。
在这两种情况下,您都应该通过分析对脚本的请求数量来确定负载的原因,如果有对外部资源的调用,请确保它们正常工作。
答案3
正如您在状态输出中看到的那样
您有一个任务正在等待启动(5 个活动任务,0 个空闲任务,6 个任务)。正如您在自己的回答中所说(我很高兴它奏效了),增加允许的子进程数量可能是一个好的解决方案 - 但优化 php-fpm 需要做很多工作,当然应该更多地考虑整个系统在进行这些配置更改之前。
可靠的指南是这里。
但无论使用静态值时你应该知道什么:
if (进程内存使用量 * max_children > RAM)
{ [crash apache] }
if (处理要求 * start_servers > CPU)
{ [崩溃 apache] }
而且总是了解你的硬件在调整这些设置之前,特别是在动态/按需时(在我看来,更容易犯错误)。
如果你正在为任何类型的关键业务 Web 服务器执行此操作,我会将所有估算值四舍五入,然后翻倍。例如,可以调用的最大进程使用 178mb,所以 200mb,而你当前在 [插入托管提供商/自己] 上的 VM 只有 1gb 的 RAM - 我会将 max_children 设置为2-- 那么当你升级虚拟机(2021 年你用 1gb 干什么??)并且服务器上有 8gb 的 RAM 时,你可以使用 max_children =18请注意,在这两个例子中,舍入都有利于额外的资源,并且在为 fpm 的用途加倍之后,留下了一大块内存供操作系统和其他后台进程使用。
调整这些设置会非常有帮助,任何使用 apache 的人都应该知道如何做 - 只需确保您的硬件可以处理您设置的软件配置。
答案4
去年我们几乎遇到过同样的问题。
抚养最多数量的孩子只能将问题推迟到以后解决。
原来,它是我们网络上为博客托管的专用服务器上的一个速度很慢的 MySQL 数据库。
我们的 PHP 配置为尝试连接 30 秒,每当这个数据库决定出现故障时,它就会占用 100 个 PHP 子进程。
我们将其降低到 1 秒,问题就解决了。我不记得数据库问题是否与网络有关,或者我们是否必须优化数据库本身。
您应该检查 2:30-3:30 时间段内的 Apache 访问日志,并确定它们是否是连接到数据库的页面。检查日志中是否存在导致服务器崩溃的 500 错误。