
该文章的未经编辑版本最初在haydenjames.io上发布,并在得到其作者许可的情况下在此处发布。
简而言之,我将讨论如何最好地配置PHP-FPM以提高吞吐量,减少延迟以及更稳定地使用处理器资源和内存。 默认情况下,PHP-FPM中的字符串PM(进程管理器)是动态的 ,如果没有足够的内存,最好安装ondemand 。 让我们比较基于php.net文档的2个控件选项,看看我最喜欢的static pm与它们在大量流量方面的区别:
pm = dynamic-子进程数是根据以下指令动态配置的: pm.max_children,pm.start_servers,pm.min_spare_servers,pm.max_spare_servers 。
pm = ondemand-进程按需创建(与动态创建不同,在服务启动时启动pm.start_servers时)。
pm = static-子进程的数量是固定的,并由参数pm.max_children指定。
有关详细信息,请参见全局php-fpm.conf指令的完整列表 。
PHP-FPM流程管理器与处理器频率控制器的相似之处
它可能似乎是题外话,但我将把它与PHP-FPM配置主题联系起来。 至少有一次没有使笔记本电脑,虚拟机或专用服务器上的处理器速度变慢的人。 还记得处理器频率的缩放比例吗? 这些选项可用于nix和Windows,它们可以通过将处理器控制器设置从按需更改 为性能* 来提高系统性能和响应速度 。 这次,让我们比较描述并看一下相似之处:
调速器=按需 -根据当前负载动态调整处理器频率。 急剧切换到最大频率,然后在空闲时间增加时降低最大频率。
调速器=保守=动态频率缩放取决于当前负载。 增加和减少频率比按需平滑。
调速器=性能 -频率始终最大。
有关详细信息,请参阅处理器频率控制器参数的完整列表 。
看到相似之处吗? 我想展示此比较,以说服您最好将pm static用于PHP-FPM。
对于处理器控制器, 性能参数有助于安全地提高性能,因为它几乎完全取决于服务器处理器的限制。 当然,除此之外,还有诸如温度,电池电量(在笔记本电脑中)和处理器以100%恒定运行的其他副作用等因素。 性能调整可提供最快的处理器性能。 例如,阅读有关Raspberry Pi中的force_turbo参数的信息 ,RPi面板将使用该参数使用性能调节器,由于CPU的时钟速度较低,因此性能改进将更加明显。
使用pm static来最大化服务器性能
PHP-FPM pm静态参数在很大程度上取决于服务器上的可用内存。 如果内存不足,最好选择ondemand或dynamic 。 另一方面,如果您有内存,则可以通过将pm static设置为最大服务器容量来避免PHP进程管理器的开销。 换句话说,如果一切都计算正确,则需要将pm.static设置为可以执行的最大PHP-FPM进程数量, 而不会造成内存或缓存不足的问题。 但是不要太高,以至于使处理器超负荷并堆积一堆等待执行的PHP-FPM操作 。

在上面的屏幕截图中,服务器已安装pm = static和pm.max_children = 100 ,这大约占用了32个可用空间中的10 GB。 在此屏幕截图中,Google Analytics(分析)大约有200位活跃用户(超过60秒)。 在此级别上,大约70%的PHP-FPM子进程仍处于空闲状态。 这意味着无论当前流量如何,PHP-FPM始终设置为最大服务器资源量。 空闲进程等待流量高峰并立即做出响应。 您不必等待pm创建子进程,然后在pm.process_idle_timeout期限到期时终止它们。 我为pm.max_requests设置了一个很高的值,因为它是一个正常工作的服务器,没有PHP中的内存泄漏。 如果您对现有和将来的PHP脚本完全有信心,则可以将pm.max_requests = 0设置为static。 但是最好随时间重新启动脚本。 安装大量查询,因为我们要避免不必要的pm开销。 例如,至少pm.max_requests = 1000-取决于pm.max_children的数量和每秒的请求数。
屏幕截图显示了Linux top命令,由u(用户)和PHP-FPM用户名过滤。 仅显示前50个左右的进程(我没有完全计算在内),但实际上,top显示了放置在终端窗口中的顶部统计信息。 在这种情况下,按%CPU(%CPU)排序。 要查看所有100个PHP-FPM进程,请运行以下命令:
top -bn1 | grep php-fpm
何时使用pm按需和动态
如果使用pm dynamic ,则会得到类似的错误:
WARNING: [pool xxxx] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 4 idle, and 59 total children
尝试更改参数,错误将不会消失 ,如本文有关Serverfault所述 。 在这种情况下,pm.min的值太小,并且由于网络流量变化很大并且具有高峰值和深下降,因此难以适当地配置pm dynamic 。 如同一篇文章中所述 ,这通常使用pm ondemand 。 但是,情况甚至更糟,因为在几乎没有流量或根本没有流量的情况下, ondemand会将空闲进程终止为零,结果,当流量发生变化时,您仍然会蒙受损失。 当然,除非您设置了巨大的等待时间。 然后最好使用pm.static +大量的pm.max_requests 。
如果您有多个PHP-FPM池,则PM 动态 (尤其是按需)可以派上用场。 例如,您在不同的池中托管多个cPanel帐户或多个网站。 我有一台服务器,例如,其中有100多个cpanel帐户和大约200个域,而pm.static甚至是dynamic都无法挽救我。 这里只需要按需,因为超过三分之二的网站根本接收不到流量或根本没有流量,并且按需所有子进程都将掉落,这将为我们节省大量内存! 幸运的是,cPanel开发人员注意到了这一点,并将默认值设置为ondemand 。 以前,当默认值为dynamic时 ,PHP-FPM通常不适合繁忙的共享服务器。 许多人使用suPHP是因为pm 动态会消耗内存,即使使用空闲池和cPanel PHP-FPM帐户也是如此。 最有可能的是,如果流量良好,您将不会被托管在具有大量PHP-FPM池的服务器上(共享托管)。
结论
如果您使用PHP-FPM且流量很大,则PHP-FPM的按需和动态流程管理器会因其固有成本而限制带宽。 检查系统并配置PHP-FPM进程以匹配最大服务器容量。 首先根据pm dynamic或ondemand的最大使用量设置pm.max_children ,然后将该值增加到内存和处理器可以正常工作而不会过度过载的水平。 您会注意到,使用pm static时 ,由于所有内容都存储在内存中,因此,随着时间的流逝,流量峰值将导致处理器的峰值减少,并且服务器和处理器的平均负载值将相等。 PHP-FPM的平均进程大小取决于Web服务器,并且需要手动配置,因此更加自动化的进程管理器- 动态和按需 -更为流行。 希望本文对您有所帮助。
UPD添加了基准图ab 。 如果PHP-FPM进程在内存中,则可以通过占用它们坐下来等待的内存来提高性能。 寻找适合自己的最佳选择。
