PHP5-FPM and 'ondemand'

I've set up a server with Nginx and PHP5-FPM, and things are running fine. However, as I add more and more sites to the server I see that the memory usage steadily increases, and I've come to the conclusion that PHP5-FPM is to "blame".

What I currently do is that I set up a separate PHP5-FPM pool for each site, and configure that pool according to expected traffic. However, with enough sites, I will in the end have a server which just sists on a rather large number of PHP5-FPM "children" which are just waiting for work.

I just found out about the ondemand PHP5-FPM mode, which allows me to configure PHP5-FPM in a way so that child processes are forked only when actually needed, and then kept alive for a given duration to process.

However, I can't really find too much details on this. What I'm most curious about is how the variables pm.max_children and pm.max_requests affect the ondemand mode (if at all). I assume that the variables pm.start_servers, pm.min_spare_servers, pm.max_spare_servers not apply to the ondemand mode.


Solution 1:

you're right, start_servers, min_spare_servers and max_spare_servers do not apply to the ondemand mode. The following variables are those that apply to ondemand mode:

  • pm.max_children
  • pm.process_idle_timeout
  • pm.max_requests

When you set pm = ondemand, FPM will fork childrens as soon as he need, always keeping children number less or equal to pm.max_children, so this variable is a upper limit on number of childrens forked at the same time.

The other two variables allows you to specify when a children has to be destroyed:

  • pm.process_idle_timeout sets how long a children waits without work before it gets destroyed. It is defined in seconds.

  • pm.max_requests defines how many requests (one at a time) a children will process before it gets destroyed. For example, if you set this variable a value of 50, a children will process 50 requests and closes itself. If FPM master process still needs another children, it will fork a new one.

In my company we use ondemand mode on FPM, and we use pm.max_requests to force recycling of fpm childrens and avoid high memory usage.

Hope this helps,

Greetings.

Solution 2:

It might be this bug https://bugs.php.net/bug.php?id=72935

TLDR; If two clients connect to PHP-FPM in ondemand mode on the same unix socket before accept() happens in the child only one gets accept()ed.