diff options
author | Paulius Sapragonas <pauliussap@gmail.com> | 2021-03-05 20:15:30 +0200 |
---|---|---|
committer | Jakub Zelenka <bukka@php.net> | 2021-03-28 20:53:58 +0100 |
commit | eac1609a847f7cca45c9c14e1b9c4d72cea04fd6 (patch) | |
tree | 203b80f304ce36679641e96ef5d8c23745858e4d | |
parent | 830d38535178920bfaae6e8e8d93fadcba4a1a7e (diff) | |
download | php-git-eac1609a847f7cca45c9c14e1b9c4d72cea04fd6.tar.gz |
Max spawn child processes rate an once
* Add functionality to expect log config options
-rw-r--r-- | sapi/fpm/fpm/fpm_conf.c | 10 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_conf.h | 1 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_process_ctl.c | 2 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_process_ctl.h | 2 | ||||
-rw-r--r-- | sapi/fpm/tests/set-pm-max-spawn-rate.phpt | 39 | ||||
-rw-r--r-- | sapi/fpm/tests/tester.inc | 42 | ||||
-rw-r--r-- | sapi/fpm/www.conf.in | 8 |
7 files changed, 100 insertions, 4 deletions
diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index 42f75a475d..72772031e4 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -132,6 +132,7 @@ static struct ini_value_parser_s ini_fpm_pool_options[] = { { "pm.start_servers", &fpm_conf_set_integer, WPO(pm_start_servers) }, { "pm.min_spare_servers", &fpm_conf_set_integer, WPO(pm_min_spare_servers) }, { "pm.max_spare_servers", &fpm_conf_set_integer, WPO(pm_max_spare_servers) }, + { "pm.max_spawn_rate", &fpm_conf_set_integer, WPO(pm_max_spawn_rate) }, { "pm.process_idle_timeout", &fpm_conf_set_time, WPO(pm_process_idle_timeout) }, { "pm.max_requests", &fpm_conf_set_integer, WPO(pm_max_requests) }, { "pm.status_path", &fpm_conf_set_string, WPO(pm_status_path) }, @@ -610,6 +611,7 @@ static void *fpm_worker_pool_config_alloc() /* {{{ */ memset(wp->config, 0, sizeof(struct fpm_worker_pool_config_s)); wp->config->listen_backlog = FPM_BACKLOG_DEFAULT; + wp->config->pm_max_spawn_rate = 32; /* 32 by default */ wp->config->pm_process_idle_timeout = 10; /* 10s by default */ wp->config->process_priority = 64; /* 64 means unset */ wp->config->process_dumpable = 0; @@ -848,7 +850,7 @@ static int fpm_conf_process_all_pools() /* {{{ */ return -1; } - /* pm.start_servers, pm.min_spare_servers, pm.max_spare_servers */ + /* pm.start_servers, pm.min_spare_servers, pm.max_spare_servers, pm.max_spawn_rate */ if (wp->config->pm == PM_STYLE_DYNAMIC) { struct fpm_worker_pool_config_s *config = wp->config; @@ -881,6 +883,11 @@ static int fpm_conf_process_all_pools() /* {{{ */ zlog(ZLOG_ALERT, "[pool %s] pm.start_servers(%d) must not be less than pm.min_spare_servers(%d) and not greater than pm.max_spare_servers(%d)", wp->config->name, config->pm_start_servers, config->pm_min_spare_servers, config->pm_max_spare_servers); return -1; } + + if (config->pm_max_spawn_rate < 1) { + zlog(ZLOG_ALERT, "[pool %s] pm.max_spawn_rate must be a positive value", wp->config->name); + return -1; + } } else if (wp->config->pm == PM_STYLE_ONDEMAND) { struct fpm_worker_pool_config_s *config = wp->config; @@ -1718,6 +1725,7 @@ static void fpm_conf_dump() /* {{{ */ zlog(ZLOG_NOTICE, "\tpm.start_servers = %d", wp->config->pm_start_servers); zlog(ZLOG_NOTICE, "\tpm.min_spare_servers = %d", wp->config->pm_min_spare_servers); zlog(ZLOG_NOTICE, "\tpm.max_spare_servers = %d", wp->config->pm_max_spare_servers); + zlog(ZLOG_NOTICE, "\tpm.max_spawn_rate = %d", wp->config->pm_max_spawn_rate); zlog(ZLOG_NOTICE, "\tpm.process_idle_timeout = %d", wp->config->pm_process_idle_timeout); zlog(ZLOG_NOTICE, "\tpm.max_requests = %d", wp->config->pm_max_requests); zlog(ZLOG_NOTICE, "\tpm.status_path = %s", STR2STR(wp->config->pm_status_path)); diff --git a/sapi/fpm/fpm/fpm_conf.h b/sapi/fpm/fpm/fpm_conf.h index cd71bb53fd..1d5eabe17c 100644 --- a/sapi/fpm/fpm/fpm_conf.h +++ b/sapi/fpm/fpm/fpm_conf.h @@ -70,6 +70,7 @@ struct fpm_worker_pool_config_s { int pm_start_servers; int pm_min_spare_servers; int pm_max_spare_servers; + int pm_max_spawn_rate; int pm_process_idle_timeout; int pm_max_requests; char *pm_status_path; diff --git a/sapi/fpm/fpm/fpm_process_ctl.c b/sapi/fpm/fpm/fpm_process_ctl.c index a2f0f935e4..d8c0bc30d1 100644 --- a/sapi/fpm/fpm/fpm_process_ctl.c +++ b/sapi/fpm/fpm/fpm_process_ctl.c @@ -431,7 +431,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{ zlog(ZLOG_DEBUG, "[pool %s] %d child(ren) have been created dynamically", wp->config->name, children_to_fork); /* Double the spawn rate for the next iteration */ - if (wp->idle_spawn_rate < FPM_MAX_SPAWN_RATE) { + if (wp->idle_spawn_rate < wp->config->pm_max_spawn_rate) { wp->idle_spawn_rate *= 2; } continue; diff --git a/sapi/fpm/fpm/fpm_process_ctl.h b/sapi/fpm/fpm/fpm_process_ctl.h index f39a489f61..03dc98e931 100644 --- a/sapi/fpm/fpm/fpm_process_ctl.h +++ b/sapi/fpm/fpm/fpm_process_ctl.h @@ -5,8 +5,6 @@ #include "fpm_events.h" -/* spawn max 32 children at once */ -#define FPM_MAX_SPAWN_RATE (32) /* 1s (in ms) heartbeat for idle server maintenance */ #define FPM_IDLE_SERVER_MAINTENANCE_HEARTBEAT (1000) /* a minimum of 130ms heartbeat for pctl */ diff --git a/sapi/fpm/tests/set-pm-max-spawn-rate.phpt b/sapi/fpm/tests/set-pm-max-spawn-rate.phpt new file mode 100644 index 0000000000..8b5f6b4eb6 --- /dev/null +++ b/sapi/fpm/tests/set-pm-max-spawn-rate.phpt @@ -0,0 +1,39 @@ +--TEST-- +FPM: set pm.max_spawn_rate +--SKIPIF-- +<?php +include "skipif.inc"; +?> +--FILE-- +<?php + +require_once "tester.inc"; + +$cfg = <<<EOT +[global] +error_log = {{FILE:LOG}} +log_level = notice +[unconfined] +listen = {{ADDR}} +pm = dynamic +pm.max_children = 5 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +pm.max_spawn_rate = 64 +EOT; + +$tester = new FPM\Tester($cfg); +$tester->start(['-t', '-t']); +$tester->expectLogConfigOptions(['pm.max_spawn_rate' => 64]); +$tester->close(); + +?> +Done +--EXPECT-- +Done +--CLEAN-- +<?php +require_once "tester.inc"; +FPM\Tester::clean(); +?> diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc index 7aab2d3aa9..9ce4c1a091 100644 --- a/sapi/fpm/tests/tester.inc +++ b/sapi/fpm/tests/tester.inc @@ -1348,6 +1348,48 @@ class Tester } /** + * Expect log config options + * + * @param array $options + * @return bool + */ + public function expectLogConfigOptions(array $options) + { + $configOptions = $this->getConfigOptions(); + foreach ($options as $name => $value) { + if (!isset($configOptions[$name])) { + return $this->error("Expected config option: {$name} = {$value} but {$name} is not set"); + } + if ($configOptions[$name] != $value) { + return $this->error( + "Expected config option: {$name} = {$value} but got: {$name} = {$configOptions[$name]}" + ); + } + } + + return true; + } + + /** + * Get set config options + * + * @return array + */ + private function getConfigOptions() + { + $options = []; + + foreach ($this->getLogLines(-1) as $line) { + preg_match('/.+NOTICE:\s+(.+)\s=\s(.+)/', $line, $matches); + if ($matches) { + $options[$matches[1]] = $matches[2]; + } + } + + return $options; + } + + /** * Print content of access log. */ public function printAccessLog() diff --git a/sapi/fpm/www.conf.in b/sapi/fpm/www.conf.in index 3d5658a65d..ebf1bb8c90 100644 --- a/sapi/fpm/www.conf.in +++ b/sapi/fpm/www.conf.in @@ -93,6 +93,8 @@ listen = 127.0.0.1:9000 ; state (waiting to process). If the number ; of 'idle' processes is greater than this ; number then some children will be killed. +; pm.max_spawn_rate - the maximum number of rate to spawn child +; processes at once. ; ondemand - no children are created at startup. Children will be forked when ; new requests will connect. The following parameter are used: ; pm.max_children - the maximum number of children that @@ -128,6 +130,12 @@ pm.min_spare_servers = 1 ; Note: Mandatory when pm is set to 'dynamic' pm.max_spare_servers = 3 +; The number of rate to spawn child processes at once. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +; Default Value: 32 +;pm.max_spawn_rate = 32 + ; The number of seconds after which an idle process will be killed. ; Note: Used only when pm is set to 'ondemand' ; Default Value: 10s |