An unedited version of article was originally published at HaydenJames.io and republished here with the author’s permission.
未经编辑的文章版本最初在HaydenJames.io上发布,并在得到作者许可的情况下在此处重新发布。
Let’s take a very quick look at how best to set up PHP-FPM for high throughput, low latency, and a more stable use of CPU and memory. By default, most setups have PHP-FPM’s PM (process manager) string set to dynamic and there’s also the common advice to use ondemand
if you suffer from available memory issues. However, let’s compare the two management options based on php.net’s documentation and also compare my favorite for high traffic setup — static pm:
让我们快速看一下如何最好地设置PHP-FPM,以实现高吞吐量,低延迟以及更稳定地使用CPU和内存。 默认情况下,大多数设置都将PHP-FPM的PM(流程管理器)字符串设置为动态,并且如果您遇到可用内存问题,也有使用ondemand
的常见建议。 但是,让我们比较基于php.net文档的两个管理选项,并比较我最喜欢的高流量设置-静态pm:
pm = dynamic: the number of child processes is set dynamically based on the following directives: pm.max_children
, pm.start_servers
, pm.min_spare_servers
, pm.max_spare_servers
.
pm = dynamic :子进程数是根据以下指令动态设置的: pm.max_children
, pm.start_servers
, pm.min_spare_servers
, pm.max_spare_servers
。
pm = ondemand: the processes spawn on demand when requested, as opposed to dynamic, where pm.start_servers
are started when the service is started.
pm = ondemand :进程是在请求时按需生成的,而不是动态的,而动态是在启动服务时启动pm.start_servers
。
pm = static: the number of child processes is fixed by pm.max_children
.
pm = static :子进程的数量由pm.max_children
固定。
See the full list of global php-fpm.conf
directives for further details.
有关更多详细信息,请参见全局php-fpm.conf
指令的完整列表 。
Now, this may seem a bit off topic, but I hope to tie it back into our PHP-FPM tuning topic. Okay, we’ve all had slow CPU issues at some point, whether it be a laptop, VM or dedicated server. Remember CPU frequency scaling? (CPUFreq governor.) These settings, available on both *nix and Windows, can improve the performance and system responsiveness by changing the CPU governor setting from ondemand to performance. This time, let’s compare the descriptions and look for similarities:
现在,这似乎有点不合时宜,但我希望将其重新绑定到我们PHP-FPM调整主题中。 好的,无论是笔记本电脑,VM还是专用服务器,我们在某些时候都遇到了CPU速度缓慢的问题。 还记得CPU频率缩放吗? ( 的CPUFreq州长 。)这些设置,两个* nix中和Windows上使用,可以通过按需 性能改变CPU州长设置提高性能和系统响应能力。 这次,让我们比较描述并寻找相似之处:
Governor = ondemand: scales CPU frequency dynamically according to current load. Jumps to the highest frequency and then scales down as the idle time increases.
Governor = ondemand :根据当前负载动态扩展CPU频率。 跳到最高频率,然后随着空闲时间的增加而缩小。
Governor = conservative: scales the frequency dynamically according to current load. Scales the frequency more gradually than ondemand.
调速器=保守的 :根据当前负载动态缩放频率。 比按需逐步调整频率。
Governor = performance: always run the CPU at the maximum frequency.
调速器=性能 :始终以最大频率运行CPU。
See the full list of CPUFreq governor options for further details.
有关更多详细信息,请参见CPUFreq调控器选项的完整列表 。
Notice the similarities? I wanted to use this comparison first, with the aim of finding the best way to write an article which recommends using pm static for PHP-FPM as your first choice.
注意到相似之处吗? 我想首先使用这种比较,目的是找到撰写文章的最佳方法,该文章建议将pm static用于PHP-FPM作为首选。
With CPU governor, the performance setting is a pretty safe performance boost because it’s almost entirely dependent on your server CPU’s limit. The only other factors would be things such as heat, battery life (laptop) and other side effects of clocking your CPU frequency to 100% permanently. Once set to performance, it is indeed the fastest setting for your CPU. For example read about the ‘force_turbo’ setting on Raspberry Pi, which forces your RPi board to use the performance governor where performance improvement is more noticeable due to the low CPU clock speeds.
使用CPU调速器,性能设置可以相当安全地提高性能,因为它几乎完全取决于服务器CPU的限制。 唯一的其他因素是热量,电池寿命(笔记本电脑)以及将CPU频率永久固定为100%的其他副作用。 一旦设置为性能,它确实是CPU最快的设置。 例如,阅读有关Raspberry Pi上的'force_turbo'设置的信息,该设置会强制您的RPi板使用性能调节器,由于CPU时钟速度较低,因此性能改善更为明显。
The PHP-FPM pm static setting depends heavily on how much free memory your server has. Basically, if you are suffering from low server memory, then pm ondemand or dynamic may be better options. On the other hand, if you have the memory available, you can avoid much of the PHP process manager (PM) overhead by setting pm static to the max capacity of your server. In other words, when you do the math, pm.static
should be set to the max amount of PHP-FPM processes that can run without creating memory availability or cache pressure issues. Also, not so high as to overwhelm CPU(s) and have a pile of pending PHP-FPM operations.
PHP-FPM pm静态设置在很大程度上取决于服务器具有多少可用内存。 基本上,如果服务器内存不足,那么按需pm或dynamic可能是更好的选择。 另一方面,如果您有可用的内存,则可以通过将pm static设置为服务器的最大容量来避免很多PHP进程管理器(PM)开销。 换句话说,在进行数学运算时,应该将pm.static
设置为可以运行的最大PHP-FPM进程数量,而不会产生内存可用性或缓存压力问题。 而且,不要太高以至于使CPU不堪重负,并且有大量待处理PHP-FPM操作。
In the screenshot above, this server has pm = static
and pm.max_children = 100
which uses a max of around 10GB of the 32GB installed. Take note of the self explanatory highlighted columns. During that screenshot there were about 200 ‘active users’ (past 60 seconds) in Google Analytics. At that level, about 70% of PHP-FPM children are still idle. This means PHP-FPM is always set to the max capacity of your server’s resources regardless of current traffic. Idle processes stay online, waiting for traffic spikes and responding immediately, rather than having to wait on the pm to spawn children and then kill them off after x pm.process_idle_timeout
expires. I have pm.max_requests
set extremely high because this is a production server with no PHP memory leaks. You can use pm.max_requests = 0
with static
if you have 110% confidence in your current and future PHP scripts. However, it’s recommended to restart scripts over time. Set the number of requests to a high number since the point is to avoid pm overhead. So for example at least pm.max_requests = 1000
depending on your number of pm.max_children
and number of requests per second.
在上面的屏幕截图中,此服务器的pm = static
和pm.max_children = 100
,它使用的最大32GB内存约为10GB。 注意自我说明突出显示的列。 在该屏幕截图中,Google Analytics(分析)中大约有200个“活跃用户”(过去60秒)。 在此级别上,大约70%PHP-FPM子级仍处于空闲状态。 这意味着无论当前流量如何,PHP-FPM始终设置为服务器资源的最大容量。 空闲进程保持在线状态,等待流量激增并立即做出响应,而不是必须等待pm来生成子代,然后在x pm.process_idle_timeout
到期后将其杀死。 我将pm.max_requests
设置得很高,因为这是一台没有PHP内存泄漏的生产服务器。 如果您对当前和将来PHP脚本有110%的信心,则可以将pm.max_requests = 0
与static
一起使用。 但是,建议一段时间后重新启动脚本。 将请求数设置为较高的数目,因为这样做的目的是避免pm开销。 因此,例如,至少pm.max_requests = 1000
具体取决于您的pm.max_children
数量和每秒的请求数量。
The screenshot uses Linux top filtered by ‘u’ (user) option and the name of the PHP-FPM user. The number of processes displayed are only the ‘top’ 50 or so (didn’t count), but basically top displays the top stats which fit in your terminal window — in this case, sorted by %CPU. To view all 100 PHP-FPM processes you can use something like:
屏幕快照使用Linux顶部 ,并按'u'(用户)选项和PHP-FPM用户名过滤。 显示的进程数仅是“ top” 50个左右(没有计数),但是基本上top显示适合您终端窗口的顶级统计信息-在这种情况下,按%CPU排序。 要查看所有100个PHP-FPM进程,您可以使用类似以下的命令:
top -bn1 | grep php-fpm
Using pm dynamic
you may have noticed errors similar to:
使用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
You may try to increase/adjust settings and still see the same error as someone describes in this Serverfault post. In that case, the pm.min
was too low and because web traffic fluctuates greatly with dips and spikes, using pm dynamic
can be difficult to tune correctly. The common advice is to use pm ondemand. However, that’s even worse, because ondemand will shut down idle processes right down to 0 when there’s little to no traffic and then you’ll end up with just as much overhead issues as traffic fluctuates — unless, of course, you set the idle timeout extremely high … in which case you should just be using pm.static
+ a high pm.max_requests
.
您可以尝试增加/调整设置,但仍然看到与该Serverfault帖子中所描述的错误相同的错误。 在这种情况下, pm.min
太低,并且由于Web流量随波峰和突增而大幅波动,因此使用pm dynamic
可能难以正确调整。 常见的建议是使用pm ondemand 。 但是,这甚至更糟,因为当流量很少或没有流量时,ondemand会将空闲进程立即关闭为0,然后您将面临流量波动带来的大量开销问题-当然,除非您设置了空闲超时极高…在这种情况下,您应该只使用pm.static
+较高的pm.max_requests
。
PM dynamic and especially ondemand can save you, however, when you have multiple PHP-FPM pools. For example, hosting multiple cPanel accounts or multiple websites under different pools. I have a server, for example, with 100+ cPanel accounts and about 200+ domains, and it would be impossible for pm.static or even dynamic to perform well. Only ondemand performs well, since more than two thirds of the websites receive little to no traffic. And with ondemand, it means all children will be shut down saving tons of server memory! Thankfully, cPanel devs figured this out and now it defaults to ondemand. Previously with dynamic as default it made PHP-FPM not an option on busy shared servers. Many would use suPHP because of pm dynamic eating up memory even on idle cPanel PHP-FPM pools/accounts. Chances are, if you receive good traffic, you won’t be hosted on a server with lots of PHP-FPM pools (shared hosting).
但是,当您有多个PHP-FPM池时,PM动态的(尤其是按需的)可以节省您的时间。 例如,在不同的池下托管多个cPanel帐户或多个网站。 例如,我有一台服务器,具有100多个cPanel帐户和大约200多个域,并且pm.static甚至dynamic都不可能表现良好。 只有按需表现良好,因为超过三分之二的网站几乎没有流量。 随需应变,这意味着将关闭所有子级,从而节省大量服务器内存! 值得庆幸的是,cPanel开发人员已经弄清楚了这一点,现在它默认为按需显示。 以前使用动态默认设置,因此它使得PHP-FPM不能在繁忙的共享服务器上使用。 由于pm动态消耗内存,即使在空闲的cPanel PHP-FPM池/帐户上,许多人也会使用suPHP。 如果您获得良好的流量,则很有可能不会将您托管在具有大量PHP-FPM池的服务器上(共享托管)。
When it comes to PHP-FPM, once you start to serve serious traffic, ondemand and dynamic process managers for PHP-FPM can limit throughput because of the inherent overhead. Know your system and set your PHP-FPM processes to match your server’s max capacity. Start with pm.max_children
set based on max usage of pm dynamic or ondemand and then increase to the point where memory and CPU can process without becoming overwhelmed. You will notice that with pm static, because you keep everything sitting in memory, traffic spikes over time cause less spikes to CPU and your server’s load and CPU averages will be smoother. The average size of your PHP-FPM process will vary per web server requiring manual tuning, thus why the more automated overhead process managers — dynamic and ondemand — are more popular recommendations. Hope this was a useful article.
当涉及到PHP-FPM时,一旦开始为大量流量提供服务,由于固有的开销,PHP-FPM的按需和动态流程管理器可能会限制吞吐量。 了解您的系统并设置PHP-FPM进程以匹配服务器的最大容量。 从根据pm dynamic或ondemand的最大使用量设置pm.max_children
开始,然后增加到可以处理内存和CPU而不会变得不知所措的地步。 您会注意到,使用pm static,因为您将所有内容都保留在内存中,所以随着时间的推移,流量峰值会导致CPU的峰值减少,并且服务器的负载和CPU平均数会更平滑。 每个需要手动调整的Web服务器PHP-FPM流程的平均大小会有所不同,因此,为什么更自动化的开销流程管理器(动态和按需)是更受欢迎的建议。 希望这是一篇有用的文章。
Update: Added A/B benchmark comparison graph. Having PHP-FPM processes sit in memory helps performance at the price of increased memory usage to have them sit in wait. Find your setup sweet-spot.
更新:添加了A / B基准比较图。 将PHP-FPM进程放在内存中有助于提高性能,但要增加内存使用量,让它们处于等待状态。 找到您的设置最佳位置。
翻译自: https://www.sitepoint.com/php-fpm-tuning-using-pm-static-max-performance/