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.