mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-21 13:16:57 +00:00
MINOR: mux-h2: make the initial window size configurable per side
For a long time the initial window size (per-stream size) was set once for both directions, frontend and backend, resulting in a tradeoff between upload speed and download fairness. This commit allows it to be configured separately for each side. The older settings remains the fallback choice when other ones are not set.
This commit is contained in:
parent
b36e512bd0
commit
9d7abda787
@ -2885,6 +2885,28 @@ tune.fd.edge-triggered { on | off } [ EXPERIMENTAL ]
|
||||
certain scenarios. This is still experimental, it may result in frozen
|
||||
connections if bugs are still present, and is disabled by default.
|
||||
|
||||
tune.h2.be.initial-window-size <number>
|
||||
Sets the HTTP/2 initial window size for outgoing connections, which is the
|
||||
number of bytes the server can respond before waiting for an acknowledgment
|
||||
from HAProxy. This setting only affects payload contents, not headers. When
|
||||
not set, the common default value set by tune.h2.initial-window-size applies.
|
||||
It can make sense to slightly increase this value to allow faster downloads
|
||||
or to reduce CPU usage on the servers, at the expense of creating unfairness
|
||||
between clients. It doesn't affect resource usage.
|
||||
See also: tune.h2.initial-window-size.
|
||||
|
||||
tune.h2.fe.initial-window-size <number>
|
||||
Sets the HTTP/2 initial window size for incoming connections, which is the
|
||||
number of bytes the client can upload before waiting for an acknowledgment
|
||||
from HAProxy. This setting only affects payload contents (i.e. the body of
|
||||
POST requests), not headers. When not set, the common default value set by
|
||||
tune.h2.initial-window-size applies. It can make sense to increase this value
|
||||
to allow faster uploads. The default value of 65536 allows up to 5 Mbps of
|
||||
bandwidth per client over a 100 ms ping time, and 500 Mbps for 1 ms ping
|
||||
time. It doesn't affect resource usage. Using too large values may cause
|
||||
clients to experience a lack of responsiveness if pages are accessed in
|
||||
parallel to large uploads. See also: tune.h2.initial-window-size.
|
||||
|
||||
tune.h2.header-table-size <number>
|
||||
Sets the HTTP/2 dynamic header table size. It defaults to 4096 bytes and
|
||||
cannot be larger than 65536 bytes. A larger value may help certain clients
|
||||
@ -2893,14 +2915,16 @@ tune.h2.header-table-size <number>
|
||||
change it.
|
||||
|
||||
tune.h2.initial-window-size <number>
|
||||
Sets the HTTP/2 initial window size, which is the number of bytes the client
|
||||
can upload before waiting for an acknowledgment from HAProxy. This setting
|
||||
only affects payload contents (i.e. the body of POST requests), not headers.
|
||||
The default value is 65536, which roughly allows up to 5 Mbps of upload
|
||||
bandwidth per client over a network showing a 100 ms ping time, or 500 Mbps
|
||||
over a 1-ms local network. It can make sense to increase this value to allow
|
||||
faster uploads, or to reduce it to increase fairness when dealing with many
|
||||
clients. It doesn't affect resource usage.
|
||||
Sets the default value for the HTTP/2 initial window size, on both incoming
|
||||
and outgoing connections. This value is used for incoming connections when
|
||||
tune.h2.fe.initial-window-size is not set, and by outgoing connections when
|
||||
tune.h2.be.initial-window-size is not set. The default value is 65536, which
|
||||
for uploads roughly allows up to 5 Mbps of bandwidth per client over a
|
||||
network showing a 100 ms ping time, or 500 Mbps over a 1-ms local network.
|
||||
Given that changing the default value will both increase upload speeds and
|
||||
cause more unfairness between clients on downloads, it is recommended to
|
||||
instead use the side-specific settings tune.h2.fe.initial-window-size and
|
||||
tune.h2.be.initial-window-size.
|
||||
|
||||
tune.h2.max-concurrent-streams <number>
|
||||
Sets the HTTP/2 maximum number of concurrent streams per connection (ie the
|
||||
|
29
src/mux_h2.c
29
src/mux_h2.c
@ -403,7 +403,9 @@ DECLARE_STATIC_POOL(pool_head_h2s, "h2s", sizeof(struct h2s));
|
||||
|
||||
/* a few settings from the global section */
|
||||
static int h2_settings_header_table_size = 4096; /* initial value */
|
||||
static int h2_settings_initial_window_size = 65536; /* initial value */
|
||||
static int h2_settings_initial_window_size = 65536; /* default initial value */
|
||||
static int h2_be_settings_initial_window_size = 0; /* backend's default initial value */
|
||||
static int h2_fe_settings_initial_window_size = 0; /* frontend's default initial value */
|
||||
static unsigned int h2_settings_max_concurrent_streams = 100;
|
||||
static int h2_settings_max_frame_size = 0; /* unset */
|
||||
|
||||
@ -1641,6 +1643,7 @@ static int h2c_send_settings(struct h2c *h2c)
|
||||
struct buffer *res;
|
||||
char buf_data[100]; // enough for 15 settings
|
||||
struct buffer buf;
|
||||
int iws;
|
||||
int mfs;
|
||||
int ret = 0;
|
||||
|
||||
@ -1670,10 +1673,15 @@ static int h2c_send_settings(struct h2c *h2c)
|
||||
chunk_memcat(&buf, str, 6);
|
||||
}
|
||||
|
||||
if (h2_settings_initial_window_size != 65535) {
|
||||
iws = (h2c->flags & H2_CF_IS_BACK) ?
|
||||
h2_be_settings_initial_window_size:
|
||||
h2_fe_settings_initial_window_size;
|
||||
iws = iws ? iws : h2_settings_initial_window_size;
|
||||
|
||||
if (iws != 65535) {
|
||||
char str[6] = "\x00\x04"; /* initial_window_size */
|
||||
|
||||
write_n32(str + 2, h2_settings_initial_window_size);
|
||||
write_n32(str + 2, iws);
|
||||
chunk_memcat(&buf, str, 6);
|
||||
}
|
||||
|
||||
@ -6893,16 +6901,23 @@ static int h2_parse_header_table_size(char **args, int section_type, struct prox
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* config parser for global "tune.h2.initial-window-size" */
|
||||
/* config parser for global "tune.h2.{be.,fe.,}initial-window-size" */
|
||||
static int h2_parse_initial_window_size(char **args, int section_type, struct proxy *curpx,
|
||||
const struct proxy *defpx, const char *file, int line,
|
||||
char **err)
|
||||
{
|
||||
int *vptr;
|
||||
|
||||
if (too_many_args(1, args, err, NULL))
|
||||
return -1;
|
||||
|
||||
h2_settings_initial_window_size = atoi(args[1]);
|
||||
if (h2_settings_initial_window_size < 0) {
|
||||
/* backend/frontend/default */
|
||||
vptr = (args[0][8] == 'b') ? &h2_be_settings_initial_window_size :
|
||||
(args[0][8] == 'f') ? &h2_fe_settings_initial_window_size :
|
||||
&h2_settings_initial_window_size;
|
||||
|
||||
*vptr = atoi(args[1]);
|
||||
if (*vptr < 0) {
|
||||
memprintf(err, "'%s' expects a positive numeric value.", args[0]);
|
||||
return -1;
|
||||
}
|
||||
@ -6977,6 +6992,8 @@ INITCALL1(STG_REGISTER, register_mux_proto, &mux_proto_h2);
|
||||
|
||||
/* config keyword parsers */
|
||||
static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
{ CFG_GLOBAL, "tune.h2.be.initial-window-size", h2_parse_initial_window_size },
|
||||
{ CFG_GLOBAL, "tune.h2.fe.initial-window-size", h2_parse_initial_window_size },
|
||||
{ CFG_GLOBAL, "tune.h2.header-table-size", h2_parse_header_table_size },
|
||||
{ CFG_GLOBAL, "tune.h2.initial-window-size", h2_parse_initial_window_size },
|
||||
{ CFG_GLOBAL, "tune.h2.max-concurrent-streams", h2_parse_max_concurrent_streams },
|
||||
|
Loading…
Reference in New Issue
Block a user