Implement "ondemand" process-manager (to allow zero children)
| Request #52569 | Implement "ondemand" process-manager (to allow zero children) | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Submitted: | 2010-08-09 20:54 UTC | Modified: | 2011-10-09 09:22 UTC |
|
||||||||||
| From: | mplomer at gmx dot de | Assigned: | fat (profile) | |||||||||||
| Status: | Closed | Package: | FPM related | |||||||||||
| PHP Version: | 5.3.3 | OS: | ||||||||||||
| Private report: | No | CVE-ID: | None | |||||||||||
[2010-08-09 20:54 UTC] mplomer at gmx dot de
Description: ------------ We are currently implementing PHP-FPM in a shared hosting environment. We have many users on one server (about 200) and we have to define one pool for each customer (each with a different uid). If PHP-FPM starts one children per customer at startup, this would kill the servers, I think. So we have to start them on demand. When using PHP via mod_fcgid/suEXEC you can define FcgidMinProcessesPerClass 0, which works fine, but in PHP-FPM this is not allowed. I tried to remove the check in fpm_conf.c: if (config->pm_min_spare_servers <= 0) if (config->pm_start_servers <= 0) but this does not really work (zero children are created at startup which is fine, but no child is created on request and the request hangs). I currently don't find the right entry point.
Patches
fpm-ondemand.v11-5.3.patch (last revision 2011-07-14 22:38 UTC by fat@php.net)fpm-ondemand.v11.patch (last revision 2011-07-14 22:27 UTC by fat@php.net)
fpm-ondemand.v10-5.3.patch (last revision 2011-07-10 17:49 UTC by fat@php.net)
fpm-ondemand.v10.patch (last revision 2011-07-10 17:49 UTC by fat@php.net)
fpm-ondemand.v9-5.3.patch (last revision 2011-07-09 12:30 UTC by fat@php.net)
fpm-ondemand.v9.patch (last revision 2011-07-09 12:30 UTC by fat@php.net)
fpm-ondemand.v8-5.3.patch (last revision 2011-07-09 00:22 UTC by fat@php.net)
fpm-ondemand.v8.patch (last revision 2011-07-09 00:21 UTC by fat@php.net)
fpm-ondemand.v7-5.3.patch (last revision 2011-07-05 23:12 UTC by fat@php.net)
fpm-ondemand.v7.patch (last revision 2011-07-05 23:08 UTC by fat@php.net)
fpm-ondemand-pm-v6 (last revision 2010-09-25 16:27 UTC by mplomer at gmx dot de)
php-fpm-ondemand-pm-v5 (last revision 2010-08-30 08:16 UTC by mplomer at gmx dot de)
fpm-ondemand.v4.patch (last revision 2010-08-27 06:27 UTC by fat@php.net)
fpm-ondemand-pm-v3 (last revision 2010-08-25 22:12 UTC by mplomer at gmx dot de)
fpm-ondemand.v2.patch.txt (last revision 2010-08-23 22:51 UTC by fat@php.net)
fpm-ondemand-pm-php53 (last revision 2010-08-10 18:01 UTC by mplomer at gmx dot de)
fpm-ondemand-pm (last revision 2010-08-09 20:14 UTC by fat@php.net)
Pull Requests
History
AllCommentsChangesGit/SVN commits
[2010-08-09 22:13 UTC] fat@php.net
-Status: Open +Status: Analyzed -Assigned To: +Assigned To: fat
[2010-08-09 22:13 UTC] fat@php.net
[2010-08-10 19:59 UTC] mplomer at gmx dot de
-Summary: Allow zero pm.start_servers/pm.min_spare_servers +Summary: Implement "ondemand" process-manager (to allow zero children)
[2010-08-10 19:59 UTC] mplomer at gmx dot de
[2010-08-24 00:54 UTC] fat@php.net
[2010-08-26 00:15 UTC] mplomer at gmx dot de
[2010-08-26 00:27 UTC] fat@php.net
[2010-08-27 08:31 UTC] fat@php.net
[2010-08-27 08:38 UTC] fat@php.net
[2010-08-30 10:18 UTC] mplomer at gmx dot de
[2010-08-30 10:21 UTC] mplomer at gmx dot de
[2010-09-04 16:26 UTC] dennisml at conversis dot de
[2010-09-05 20:42 UTC] fat@php.net
[2010-09-13 03:30 UTC] dennisml at conversis dot de
Is v5 of the patch known not to work with fpm in php 5.3.3? When applying the patch I get the following segfault: Program received signal SIGSEGV, Segmentation fault. 0x00000000005cf319 in fpm_env_conf_wp (wp=<value optimized out>) at /home/dennis/php-5.3.3/sapi/fpm/fpm/fpm_env.c:141 141 if (*kv->value == '$') {[2010-09-13 06:27 UTC] fat@php.net
[2010-09-25 18:26 UTC] mplomer at gmx dot de
[2010-11-12 01:28 UTC] luca at fantacast dot it
[2010-11-12 01:53 UTC] fat@php.net
[2010-11-12 02:30 UTC] luca at fantacast dot it
[2011-06-11 10:22 UTC] denoc at gmx dot de
[2011-06-11 10:38 UTC] mplomer at gmx dot de
[2011-07-05 19:15 UTC] fat@php.net
[2011-07-06 10:44 UTC] dbetz at df dot eu
[2011-07-06 12:12 UTC] fat@php.net
[2011-07-07 02:34 UTC] dbetz at df dot eu
[2011-07-08 05:38 UTC] dbetz at df dot eu
[2011-07-08 05:43 UTC] fat@php.net
[2011-07-08 06:00 UTC] dbetz at df dot eu
Hm .. i can only see tons of: 20983 poll([{fd=4, events=POLLIN}], 1, 108) = 0 (Timeout) 20983 clock_gettime(CLOCK_MONOTONIC, {4578918, 852647570}) = 0 20983 clock_gettime(CLOCK_MONOTONIC, {4578918, 852702140}) = 0 20983 clock_gettime(CLOCK_MONOTONIC, {4578918, 852754708}) = 0 20983 clock_gettime(CLOCK_MONOTONIC, {4578918, 852807040}) = 0 20983 poll([{fd=4, events=POLLIN}], 1, 130) = 0 (Timeout) 20983 clock_gettime(CLOCK_MONOTONIC, {4578918, 983213866}) = 0 20983 clock_gettime(CLOCK_MONOTONIC, {4578918, 983267442}) = 0 20983 clock_gettime(CLOCK_MONOTONIC, {4578918, 983323753}) = 0 20983 clock_gettime(CLOCK_MONOTONIC, {4578918, 983368483}) = 0 and then thousands of: 20983 munmap(0xae151000, 1040) = 0 20983 munmap(0xae150000, 1040) = 0 20983 munmap(0xae14f000, 1040) = 0 20983 munmap(0xae14e000, 1040) = 0 20983 munmap(0xae14d000, 1040) = 0 The socket gets created here: 20983 socket(PF_FILE, SOCK_STREAM, 0) = 6 20983 setsockopt(6, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 20983 unlink("/etc/httpd/fastcgi/dynamic/5-53LATEST-wordpressmit.imageupgrade2.domainfactory-kunde.de") = -1 ENOENT (No such file or directory) 20983 umask(0111) = 027 20983 bind(6, {sa_family=AF_FILE, path="/etc/httpd/fastcgi/dynamic/5-53LATEST-wordpressmit.imageupgrade2.domainfactory-kunde.de"}, 110) = 0 20983 umask(027) = 0111 20983 listen(6, 128) = 0 When making an request nothing happens in the strace :-([2011-07-08 19:38 UTC] fat@php.net
[2011-07-08 20:24 UTC] fat@php.net
[2011-07-09 08:33 UTC] fat@php.net
[2011-07-09 11:08 UTC] trollofdarkness at gmail dot com
[2011-07-09 11:47 UTC] trollofdarkness at gmail dot com
[2011-07-10 11:02 UTC] fat@php.net
[2011-07-10 12:32 UTC] trollofdarkness at gmail dot com
[2011-07-10 12:59 UTC] fat@php.net
[2011-07-10 13:32 UTC] mplomer at gmx dot de
[2011-07-10 13:52 UTC] fat@php.net
[2011-07-10 14:38 UTC] trollofdarkness at gmail dot com
[2011-07-10 15:50 UTC] trollofdarkness at gmail dot com
[2011-07-10 16:01 UTC] fat@php.net
[2011-07-10 16:40 UTC] trollofdarkness at gmail dot com
[2011-07-10 17:38 UTC] trollofdarkness at gmail dot com
[2011-07-10 18:03 UTC] fat@php.net
[2011-07-10 18:20 UTC] trollofdarkness at gmail dot com
[2011-07-11 02:36 UTC] dbetz at df dot eu
[2011-07-11 04:09 UTC] fat@php.net
[2011-07-14 18:47 UTC] fat@php.net
[2011-07-15 08:47 UTC] dbetz at df dot eu
[2011-09-14 21:57 UTC] shadow+dphp at la3 dot org
Since there has been no activity on this issue for a while, and I think it would be *very* good to have this ondemand process manager on stable releases as soon as possible, I have decided to try the patch by myself and report the results. Also, I am a die-hard Debian user, so I tried the patch (v11-5.3) with the latest available Debian packages in sid (php 5.3.8 + a number of other patches). I found a minor issue at compile time, due to the fact that the "sapi/fpm/fpm/events" folder is not created by the Makefile within the build directory structure (if you specify a build directory separated from the sources). I solved this issue easily by inserting a new line in the "sapi/fpm/Makefile.frag" file: $(builddir)/fpm: @mkdir -p $(builddir)/fpm + @mkdir -p $(builddir)/fpm/events After this minor correction everything compiled well. Thus, I proceeded to run some tests, using apache (Apache/2.2.20) + mod_fastcgi (2.4.7~0910052141-1) as the php5-fpm frontend. In this setup, I created a separate virtual host in front of each pool, and used the following apache config in there: <IfModule mod_fastcgi.c> ScriptAlias /fcgi-bin/ "/var/www/virtual/pool.test.com/fcgi-bin/" FastCGIExternalServer /var/www/virtual/pool.test.com/fcgi-bin/php-cgi \ -socket /var/lib/php5/pools/pool.test.com AddHandler php-fastcgi .php Action php-fastcgi /fcgi-bin/php-cgi </IfModule> The sockets themselves are owned by the apache's user (www-data), whereas the php interpreters run under a different user for each pool. Results: General - Pool has to start with 0 children - OK - The "ondemand" pm can be enabled - OK - All three pm's can be enabled at the same time (for different pools, obviously) - OK Concurrent requests - Children has to be forked immediately on new requests without delay - OK - Idle children has to be killed after pm.process_idle_timeout + 0-1s - OK - When there are more than one idle children, kill only one per second PER POOL - Almost OK (only does it if pm.process_idle_timeout > 1) Reaching pm.max_children limit - No more processes has to be created - OK - Requests have to wait until one child becomes idle and then get handled immediately without further delay - OK - When limit is reached, issue a warning and increase status counter (and do this only once) - OK: [14-Sep-2011 23:16:07] WARNING: [pool site1.test.com] server reached max_children setting (4), consider raising it - Warning is re-issued after children count decreases and hit the limit again - OK CPU burns - When reaching max_children limit, pause libevent callback and reenable it in the maintenance routine, to avoid CPU burns - OK/DUNNO CPU usage does not spike under these conditions, but I do not know anything about libevent. - When children takes too long to accept() the request, avoid CPU burn - OK/DUNNO Tried with "ab -c300", no CPU burns observed. Observations - "ondemand" spawns new children *way* faster than "dynamic" does - each "dynamic" process consumes about 0.1% cpu time while idle, whereas idle "ondemand" and "static" pools do not impose any load at all. Problems - pm.min_spare_servers default value if unspecified in the pool config is 0, whereas the default pm is "dynamic". - pm.max_spare_servers default value if unspecified in the pool config is 0. Final note: Jerome, the ondemand process manager is *amazing*. If it combines well with the global maximum number of processes from #55166 , this is effectively the holy grail of php for virtual hosting companies. Big big congratulations and do not hesitate to ask me for any further info/tests that you need to make this a reality![2011-09-17 10:01 UTC] uros dot gruber at gmail dot com
[2011-10-08 21:06 UTC] fat@php.net
-Status: Analyzed +Status: Closed
[2011-10-08 21:06 UTC] fat@php.net
[2011-10-09 07:57 UTC] damien at commerceguys dot com
[2011-10-09 09:22 UTC] fat@php.net
[2012-11-09 12:46 UTC] eugene at zhegan dot in