* When mod_http2 is loaded more then ThreadsPerChild backend connections can
be useful as mod_http2 has an additional thread pool on top of
ThreadsPerChild.
But leave the default with ThreadsPerChild.
* Add some some comment why we do not limit hmax any longer
mod_proxy: follow up to r1822849.
Get the help(er) of mod_http2 to determine how much connections should
be handled in the reslist by default (i.e. max_threads).
mod_proxy: follow up to r1822849 and r1822878.
Does r1822878's "static" APR_RETRIEVE_OPTIONAL_FN work if, say, mod_proxy is
builtin but mod_http2 isn't?
Not worth taking the risk here since it's not a fast path...
Note: if this is an issue, I'm afraid it applies elsewhere too.
mod_proxy: follow up to r1822849 and r1822879.
Fix my maths, thanks Stefan and RĂ¼diger!
needs mod_http2.h
* Add missing CHANGES entry for revisions
1822849,
1822858,
1822878,
1822879,
1822883,
1828485
Submitted by: rpluem, ylavic, ylavic, ylavic, gsmith, rpluem
Reviewed by: rpluem, jim, ylavic
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@
1832485 13f79535-47bb-0310-9956-
ffa450edef68
-*- coding: utf-8 -*-
Changes with Apache 2.4.34
+ *) mod_proxy: Do not restrict the maximum pool size for backend connections
+ any longer by the maximum number of threads per process and use a better
+ default if mod_http2 is loaded.
+ [Yann Ylavic, Ruediger Pluem, Stefan Eissing, Gregg Smith]
+
*) core: Preserve the original HTTP request method in the '%<m' LogFormat
when an path-based ErrorDocument is used. PR 62186.
[Micha Lenk <micha lenk.info>]
return "value must be On or Off";
}
+void h2_get_num_workers(server_rec *s, int *minw, int *maxw)
+{
+ int threads_per_child = 0;
+ const h2_config *config = h2_config_sget(s);
+
+ *minw = h2_config_geti(config, H2_CONF_MIN_WORKERS);
+ *maxw = h2_config_geti(config, H2_CONF_MAX_WORKERS);
+ ap_mpm_query(AP_MPMQ_MAX_THREADS, &threads_per_child);
+
+ if (*minw <= 0) {
+ *minw = threads_per_child;
+ }
+ if (*maxw <= 0) {
+ /* As a default, this seems to work quite well under mpm_event.
+ * For people enabling http2 under mpm_prefork, start 4 threads unless
+ * configured otherwise. People get unhappy if their http2 requests are
+ * blocking each other. */
+ *maxw = 3 * (*minw) / 2;
+ if (*maxw < 4) {
+ *maxw = 4;
+ }
+ }
+}
+
#define AP_END_CMD AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
const command_rec h2_cmds[] = {
int h2_config_geti(const h2_config *conf, h2_config_var_t var);
apr_int64_t h2_config_geti64(const h2_config *conf, h2_config_var_t var);
+void h2_get_num_workers(server_rec *s, int *minw, int *maxw);
+
void h2_config_init(apr_pool_t *pool);
const struct h2_priority *h2_config_get_priority(const h2_config *conf,
h2_config_init(pool);
- minw = h2_config_geti(config, H2_CONF_MIN_WORKERS);
- maxw = h2_config_geti(config, H2_CONF_MAX_WORKERS);
- if (minw <= 0) {
- minw = max_threads_per_child;
- }
- if (maxw <= 0) {
- /* As a default, this seems to work quite well under mpm_event.
- * For people enabling http2 under mpm_prefork, start 4 threads unless
- * configured otherwise. People get unhappy if their http2 requests are
- * blocking each other. */
- maxw = H2MAX(3 * minw / 2, 4);
- }
+ h2_get_num_workers(s, &minw, &maxw);
idle_secs = h2_config_geti(config, H2_CONF_MAX_WORKER_IDLE_SECS);
ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
h2_mplx_req_engine_done(ngn, r_conn, status);
}
+static void http2_get_num_workers(server_rec *s, int *minw, int *maxw)
+{
+ h2_get_num_workers(s, minw, maxw);
+}
+
/* Runs once per created child process. Perform any process
* related initionalization here.
*/
APR_REGISTER_OPTIONAL_FN(http2_req_engine_push);
APR_REGISTER_OPTIONAL_FN(http2_req_engine_pull);
APR_REGISTER_OPTIONAL_FN(http2_req_engine_done);
+ APR_REGISTER_OPTIONAL_FN(http2_get_num_workers);
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks");
http2_req_engine_done, (h2_req_engine *engine,
conn_rec *rconn,
apr_status_t status));
+
+APR_DECLARE_OPTIONAL_FN(void,
+ http2_get_num_workers, (server_rec *s,
+ int *minw, int *max));
+
#endif
APACHE_MODULE(proxy_express, mass reverse-proxy module. Requires --enable-proxy., , , most, , proxy)
APACHE_MODULE(proxy_hcheck, [reverse-proxy health-check module. Requires --enable-proxy and --enable-watchdog.], , , most, , [proxy,watchdog])
-APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
+APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current -I\$(top_srcdir)/modules/http2])
module_selection=$save_module_selection
module_default=$save_module_default
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Release\mod_proxy_src" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../ssl" /I "../http2" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Release\mod_proxy_src" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Debug\mod_proxy_src" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../ssl" /I "../http2" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Debug\mod_proxy_src" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
#include "ajp.h"
#include "scgi.h"
+#include "mod_http2.h" /* for http2_get_num_workers() */
+
#if APR_HAVE_UNISTD_H
#include <unistd.h> /* for getpid() */
#endif
PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, server_rec *s, apr_pool_t *p)
{
+ APR_OPTIONAL_FN_TYPE(http2_get_num_workers) *get_h2_num_workers;
apr_status_t rv = APR_SUCCESS;
- int mpm_threads;
+ int max_threads, minw, maxw;
if (worker->s->status & PROXY_WORKER_INITIALIZED) {
/* The worker is already initialized */
worker->s->is_address_reusable = 1;
}
- ap_mpm_query(AP_MPMQ_MAX_THREADS, &mpm_threads);
- if (mpm_threads > 1) {
- /* Set hard max to no more then mpm_threads */
- if (worker->s->hmax == 0 || worker->s->hmax > mpm_threads) {
- worker->s->hmax = mpm_threads;
+ /*
+ * When mod_http2 is loaded we might have more threads since it has
+ * its own pool of processing threads.
+ */
+ ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads);
+ get_h2_num_workers = APR_RETRIEVE_OPTIONAL_FN(http2_get_num_workers);
+ if (get_h2_num_workers) {
+ get_h2_num_workers(s, &minw, &maxw);
+ /* So now the max is:
+ * max_threads-1 threads for HTTP/1 each requiring one connection
+ * + one thread for HTTP/2 requiring maxw connections
+ */
+ max_threads = max_threads - 1 + maxw;
+ }
+ if (max_threads > 1) {
+ /* Default hmax is max_threads to scale with the load and never
+ * wait for an idle connection to proceed.
+ */
+ if (worker->s->hmax == 0) {
+ worker->s->hmax = max_threads;
}
if (worker->s->smax == -1 || worker->s->smax > worker->s->hmax) {
worker->s->smax = worker->s->hmax;