Loading...
Real Time Concepts

The PHP-FPM Ondemand Process Manager

Php-fpm Pool Configuration

The PM section of the php-fpm pool (e.g.v/etc/php-fpm.d/domain.com.conf, in Red Hat/CentOS) should look something like this:

pm = ondemand
pm.max_children = 20
pm.max_requests = 100
pm.process_idle_timeout = 10s

These are the only configuration options relevant for “ondemand.” Here is an explanation of their meaning:

  • pm – This selects the “ondemand” PM, as opposed to “static” or “dynamic.”
  • pm.max_children – This sets a limit on the total number of php-fpm child processes that can exist at one time for the pool. Ideally, set it high enough to handle legitimate traffic, but cap it so a DOS attack can’t spin up an unlimited number of php-fpm child processes.
  • pm.max_requests – This causes a php-fpm child process to “recycle” (be killed and replaced by a new one) if it lives long enough to handle this many requests. I think it’s a good idea to set this value, as php-fpm child processes tend to grow in memory usage over time, so you don’t want them to live forever. But if the pool is truly a good candidate for the “ondemand” PM, then this limit may never be hit.
  • pm.process_idle_timeout – When a child process finishes a request, it becomes idle. By default, php-fpm doesn’t kill off an idle process immediately, it waits until it has been idle for this length of time before killing it off. So if another request comes in before the idle timeout expires, the process is ready to go, and can handle that next request right away. This is a performance optimization. The default value is 10 seconds; raising it will potentially save time by not having to spin up a new php-fpm child process for some requests. But raising it also increases the average number of idle php-fpm child processes, which do consume memory. So raising this value optimizies performance over memory conservation. Lowering this value makes the pool behave more like a true “ondemand” pool.

Apache Configuration

There is a “gotcha” here that needs to be pointed out. Our basic Apache 2.4/php-fpm configuration article suggests using a snippet like this in the  virtual host.

<Proxy “unix:/var/run/php-fpm/default.sock|fcgi://php-fpm”>
# we must declare a parameter in here (doesn’t matter which) or it’ll not register the proxy ahead of
time
ProxySet disablereuse=off
</Proxy>

That harmless-looking disablereuse=off setting causes Apache to make a persistent connection with a php-fpm child process. So once the request is handled, the connection remains. As a result, php-fpm sees the child process as busy, not idle, and it will never kill it off until Apache releases that connection (usually that happens when the Apache worker terminates). So this kind of setup negates the benefits of the “ondemand” process manager, because you’ll end up with lots of idle php-fpm child processes over time.

Note that disablereuse=on is a default setting, which should work well with the “ondemand” PM. But if you do set it, and you are using the “ondemand” PM, make sure you use either disablereuse=on or enablereuse=off (these both have the same meaning) in your Apache configuration.

References

Leave a Reply

Your email address will not be published. Required fields are marked *