diff options
author | Yann Ylavic <ylavic@apache.org> | 2021-10-15 12:29:00 +0200 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2021-10-15 12:29:00 +0200 |
commit | 4f9e7cf5d7dda9011afee1b886f5c27eec77d148 (patch) | |
tree | 6b13a380a52f6cc3006030909624654e38fec650 /server/mpm/event/event.c | |
parent | * mod_http2: hopeful (as always) fix for the stalling in 400_20. (diff) | |
download | apache2-4f9e7cf5d7dda9011afee1b886f5c27eec77d148.tar.xz apache2-4f9e7cf5d7dda9011afee1b886f5c27eec77d148.zip |
mpm_event: Restart stopping of idle children after a load peak. PR 65626.
r1770752 added an heuristic to avoid stopping children when the load triggers
MaxSpareThreads but children take some time to shut down until the point where
active_daemons_limit/ServerLimit is reached (scoreboard full) and no child gets
created to handle incoming connections.
However when this happens there is nothing to stop children again when the load
settles down (besides MaxRequestsPerChild, which may be 0) so let's restart to
stop children again if/when idle_thread_count reaches max_workers / 4.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1894285 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | server/mpm/event/event.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index aa6304042a..2e7bb6bfdb 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -3187,7 +3187,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) * gracefully finishing processes may accumulate, filling up the * scoreboard. To avoid running out of scoreboard entries, we * don't shut down more processes when the total number of processes - * is high. + * is high, until there are more than max_workers/4 idle threads. * * XXX It would be nice if we could * XXX - kill processes without keepalive connections first @@ -3195,13 +3195,19 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) * XXX depending on server load, later be able to resurrect them * or kill them */ - if (retained->total_daemons <= active_daemons_limit && - retained->total_daemons < server_limit) { + if ((retained->total_daemons <= active_daemons_limit + && retained->total_daemons < server_limit) + /* The above test won't transition from true to false until a child + * exits by itself (i.e. MaxRequestsPerChild reached), so the below + * test makes sure that the situation unblocks when the load falls + * significantly (regardless of MaxRequestsPerChild, e.g. 0) */ + || idle_thread_count > max_workers/4 / num_buckets) { /* Kill off one child */ ap_mpm_podx_signal(retained->buckets[child_bucket].pod, AP_MPM_PODX_GRACEFUL); retained->idle_spawn_rate[child_bucket] = 1; } else { + /* Still busy enough, don't kill */ ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf, "Not shutting down child: total daemons %d / " "active limit %d / ServerLimit %d", |