mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MINOR: compression: maximum compression rate limit
This patch adds input and output rate calcutation on the HTTP compresion feature. Compression can be limited with a maximum rate value in kilobytes per second. The rate is set with the global 'maxcomprate' option. You can change this value dynamicaly with 'set rate-limit http-compression global' on the UNIX socket.
This commit is contained in:
parent
f3747837e5
commit
d85f917daf
@ -455,6 +455,7 @@ The following keywords are supported in the "global" section :
|
|||||||
* Performance tuning
|
* Performance tuning
|
||||||
- maxconn
|
- maxconn
|
||||||
- maxconnrate
|
- maxconnrate
|
||||||
|
- maxcomprate
|
||||||
- maxpipes
|
- maxpipes
|
||||||
- maxsslconn
|
- maxsslconn
|
||||||
- noepoll
|
- noepoll
|
||||||
@ -672,6 +673,15 @@ maxconnrate <number>
|
|||||||
value close to its expected share. Also, lowering tune.maxaccept can improve
|
value close to its expected share. Also, lowering tune.maxaccept can improve
|
||||||
fairness.
|
fairness.
|
||||||
|
|
||||||
|
maxcomprate <number>
|
||||||
|
Sets the maximum per-process input compression rate to <number> kilobytes
|
||||||
|
pers second. For each session, if the maximum is reached, the compression
|
||||||
|
level will be decreased during the session. If the maximum is reached at the
|
||||||
|
beginning of a session, the session will not compress at all. If the maximum
|
||||||
|
is not reached, the compression level will be increased up to
|
||||||
|
tune.comp.maxlevel. A value of zero means there is no limit, this is the
|
||||||
|
default value.
|
||||||
|
|
||||||
maxpipes <number>
|
maxpipes <number>
|
||||||
Sets the maximum per-process number of pipes to <number>. Currently, pipes
|
Sets the maximum per-process number of pipes to <number>. Currently, pipes
|
||||||
are only used by kernel-based tcp splicing. Since a pipe contains two file
|
are only used by kernel-based tcp splicing. Since a pipe contains two file
|
||||||
@ -11110,6 +11120,11 @@ set rate-limit connections global <value>
|
|||||||
applies to all frontends and the change has an immediate effect. The value
|
applies to all frontends and the change has an immediate effect. The value
|
||||||
is passed in number of connections per second.
|
is passed in number of connections per second.
|
||||||
|
|
||||||
|
set rate-limit http-compression global <value>
|
||||||
|
Change the maximum input compression rate, which is set by the global
|
||||||
|
'maxcomprate' setting. A value of zero disables the limitation. The value is
|
||||||
|
passed in number of kilobytes per second.
|
||||||
|
|
||||||
set table <table> key <key> data.<data_type> <value>
|
set table <table> key <key> data.<data_type> <value>
|
||||||
Create or update a stick-table entry in the table. If the key is not present,
|
Create or update a stick-table entry in the table. If the key is not present,
|
||||||
an entry is inserted. See stick-table in section 4.2 to find all possible
|
an entry is inserted. See stick-table in section 4.2 to find all possible
|
||||||
|
@ -80,7 +80,10 @@ struct global {
|
|||||||
char *connect_default_ciphers;
|
char *connect_default_ciphers;
|
||||||
#endif
|
#endif
|
||||||
struct freq_ctr conn_per_sec;
|
struct freq_ctr conn_per_sec;
|
||||||
|
struct freq_ctr comp_bps_in; /* bytes per second, before http compression */
|
||||||
|
struct freq_ctr comp_bps_out; /* bytes per second, after http compression */
|
||||||
int cps_lim, cps_max;
|
int cps_lim, cps_max;
|
||||||
|
int comp_rate_lim; /* HTTP compression rate limit */
|
||||||
int maxpipes; /* max # of pipes */
|
int maxpipes; /* max # of pipes */
|
||||||
int maxsock; /* max # of sockets */
|
int maxsock; /* max # of sockets */
|
||||||
int rlimit_nofile; /* default ulimit-n value : 0=unset */
|
int rlimit_nofile; /* default ulimit-n value : 0=unset */
|
||||||
|
@ -844,6 +844,14 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
|||||||
}
|
}
|
||||||
global.cps_lim = atol(args[1]);
|
global.cps_lim = atol(args[1]);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(args[0], "maxcomprate")) {
|
||||||
|
if (*(args[1]) == 0) {
|
||||||
|
Alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
global.comp_rate_lim = atoi(args[1]) * 1024;
|
||||||
|
}
|
||||||
else if (!strcmp(args[0], "maxpipes")) {
|
else if (!strcmp(args[0], "maxpipes")) {
|
||||||
if (global.maxpipes != 0) {
|
if (global.maxpipes != 0) {
|
||||||
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
|
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <types/compression.h>
|
#include <types/compression.h>
|
||||||
|
|
||||||
#include <proto/compression.h>
|
#include <proto/compression.h>
|
||||||
|
#include <proto/freq_ctr.h>
|
||||||
#include <proto/proto_http.h>
|
#include <proto/proto_http.h>
|
||||||
|
|
||||||
|
|
||||||
@ -261,6 +262,10 @@ int http_compression_buffer_end(struct session *s, struct buffer **in, struct bu
|
|||||||
|
|
||||||
to_forward = ob->i;
|
to_forward = ob->i;
|
||||||
|
|
||||||
|
/* update input rate */
|
||||||
|
if (s->comp_ctx.cur_lvl > 0)
|
||||||
|
update_freq_ctr(&global.comp_bps_in, ib->o - ob->o);
|
||||||
|
|
||||||
/* copy the remaining data in the tmp buffer. */
|
/* copy the remaining data in the tmp buffer. */
|
||||||
if (ib->i > 0) {
|
if (ib->i > 0) {
|
||||||
left = ib->i - bi_contig_data(ib);
|
left = ib->i - bi_contig_data(ib);
|
||||||
@ -276,6 +281,9 @@ int http_compression_buffer_end(struct session *s, struct buffer **in, struct bu
|
|||||||
*in = ob;
|
*in = ob;
|
||||||
*out = ib;
|
*out = ib;
|
||||||
|
|
||||||
|
if (s->comp_ctx.cur_lvl > 0)
|
||||||
|
update_freq_ctr(&global.comp_bps_out, to_forward);
|
||||||
|
|
||||||
/* forward the new chunk without remaining data */
|
/* forward the new chunk without remaining data */
|
||||||
b_adv(ob, to_forward);
|
b_adv(ob, to_forward);
|
||||||
|
|
||||||
@ -490,6 +498,23 @@ int deflate_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag)
|
|||||||
out_len = (out->size - buffer_len(out)) - strm->avail_out;
|
out_len = (out->size - buffer_len(out)) - strm->avail_out;
|
||||||
out->i += out_len;
|
out->i += out_len;
|
||||||
|
|
||||||
|
/* compression rate limit */
|
||||||
|
if (global.comp_rate_lim > 0) {
|
||||||
|
|
||||||
|
if (read_freq_ctr(&global.comp_bps_out) > global.comp_rate_lim) {
|
||||||
|
/* decrease level */
|
||||||
|
if (comp_ctx->cur_lvl > 0) {
|
||||||
|
comp_ctx->cur_lvl--;
|
||||||
|
deflateParams(&comp_ctx->strm, comp_ctx->cur_lvl, Z_DEFAULT_STRATEGY);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (comp_ctx->cur_lvl < global.comp_rate_lim) {
|
||||||
|
/* increase level */
|
||||||
|
comp_ctx->cur_lvl++ ;
|
||||||
|
deflateParams(&comp_ctx->strm, comp_ctx->cur_lvl, Z_DEFAULT_STRATEGY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return out_len;
|
return out_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,8 +1246,21 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcmp(args[2], "http-compression") == 0) {
|
||||||
|
if (strcmp(args[3], "global") == 0) {
|
||||||
|
int v;
|
||||||
|
|
||||||
|
v = atoi(args[4]);
|
||||||
|
global.comp_rate_lim = v * 1024; /* Kilo to bytes. */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
si->applet.ctx.cli.msg = "'set rate-limit http-compression' only supports 'global'.\n";
|
||||||
|
si->applet.st0 = STAT_CLI_PRINT;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
si->applet.ctx.cli.msg = "'set rate-limit' only supports 'connections'.\n";
|
si->applet.ctx.cli.msg = "'set rate-limit' supports 'connections' and 'http-compression'.\n";
|
||||||
si->applet.st0 = STAT_CLI_PRINT;
|
si->applet.st0 = STAT_CLI_PRINT;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1708,6 +1721,8 @@ static int stats_dump_raw_to_buffer(struct stream_interface *si)
|
|||||||
"ConnRate: %d\n"
|
"ConnRate: %d\n"
|
||||||
"ConnRateLimit: %d\n"
|
"ConnRateLimit: %d\n"
|
||||||
"MaxConnRate: %d\n"
|
"MaxConnRate: %d\n"
|
||||||
|
"CompressBpsIn: %u\n"
|
||||||
|
"CompressBpsOut: %u\n"
|
||||||
"Tasks: %d\n"
|
"Tasks: %d\n"
|
||||||
"Run_queue: %d\n"
|
"Run_queue: %d\n"
|
||||||
"Idle_pct: %d\n"
|
"Idle_pct: %d\n"
|
||||||
@ -1724,6 +1739,7 @@ static int stats_dump_raw_to_buffer(struct stream_interface *si)
|
|||||||
global.maxsock, global.maxconn, global.hardmaxconn, global.maxpipes,
|
global.maxsock, global.maxconn, global.hardmaxconn, global.maxpipes,
|
||||||
actconn, pipes_used, pipes_free,
|
actconn, pipes_used, pipes_free,
|
||||||
read_freq_ctr(&global.conn_per_sec), global.cps_lim, global.cps_max,
|
read_freq_ctr(&global.conn_per_sec), global.cps_lim, global.cps_max,
|
||||||
|
read_freq_ctr(&global.comp_bps_in), read_freq_ctr(&global.comp_bps_out),
|
||||||
nb_tasks_cur, run_queue_cur, idle_pct,
|
nb_tasks_cur, run_queue_cur, idle_pct,
|
||||||
global.node, global.desc?global.desc:""
|
global.node, global.desc?global.desc:""
|
||||||
);
|
);
|
||||||
|
@ -113,6 +113,7 @@ struct global global = {
|
|||||||
.req_count = 0,
|
.req_count = 0,
|
||||||
.logsrvs = LIST_HEAD_INIT(global.logsrvs),
|
.logsrvs = LIST_HEAD_INIT(global.logsrvs),
|
||||||
.maxzlibmem = 0,
|
.maxzlibmem = 0,
|
||||||
|
.comp_rate_lim = 0,
|
||||||
.unix_bind = {
|
.unix_bind = {
|
||||||
.ux = {
|
.ux = {
|
||||||
.uid = -1,
|
.uid = -1,
|
||||||
|
@ -2087,6 +2087,11 @@ int select_compression_response_header(struct session *s, struct buffer *res)
|
|||||||
|
|
||||||
ctx.idx = 0;
|
ctx.idx = 0;
|
||||||
|
|
||||||
|
/* limit compression rate */
|
||||||
|
if (global.comp_rate_lim > 0)
|
||||||
|
if (read_freq_ctr(&global.comp_bps_in) > global.comp_rate_lim)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
/* initialize compression */
|
/* initialize compression */
|
||||||
if (s->comp_algo->init(&s->comp_ctx, global.tune.comp_maxlevel) < 0)
|
if (s->comp_algo->init(&s->comp_ctx, global.tune.comp_maxlevel) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user