]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: compression: CPU usage limit
authorWilliam Lallemand <wlallemand@exceliance.fr>
Tue, 20 Nov 2012 16:01:01 +0000 (17:01 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 21 Nov 2012 01:15:16 +0000 (02:15 +0100)
New option 'maxcompcpuusage' in global section.
Sets the maximum CPU usage HAProxy can reach before stopping the
compression for new requests or decreasing the compression level of
current requests.  It works like 'maxcomprate' but with the Idle.

doc/configuration.txt
include/proto/compression.h
src/cfgparse.c
src/compression.c
src/proto_http.c

index 2229dde53c70506a321503a0f5a8da7a707be132..3af744419acad8fc81b4f9a69c6657312a71573e 100644 (file)
@@ -456,6 +456,7 @@ The following keywords are supported in the "global" section :
    - maxconn
    - maxconnrate
    - maxcomprate
+   - maxcompcpuusage
    - maxpipes
    - maxsslconn
    - noepoll
@@ -697,6 +698,16 @@ maxcomprate <number>
   tune.comp.maxlevel.  A value of zero means there is no limit, this is the
   default value.
 
+maxcompcpuusage <number>
+  Sets the maximum CPU usage HAProxy can reach before stopping the compression
+  for new requests or decreasing the compression level of current requests.
+  It works like 'maxcomprate' but measures CPU usage instead of incoming data
+  bandwidth. The value is expressed in percent of the CPU used by haproxy. In
+  case of multiple processes (nbproc > 1), each process manages its individual
+  usage. A value of 100 disable the limit. The default value is 100. Setting
+  a lower value will prevent the compression work from slowing the whole
+  process down and from introducing high latencies.
+
 maxpipes <number>
   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
@@ -722,7 +733,6 @@ maxzlibmem <number>
   with "show info" on the line "MaxZlibMemUsage", the memory used by zlib is
   "ZlibMemUsage" in bytes.
 
-
 noepoll
   Disables the use of the "epoll" event polling system on Linux. It is
   equivalent to the command-line argument "-de". The next polling system
index 0eaa21604046e6283b07ef3cc51ba2383a7f84d0..a2e80b801de9422beb966a1b08d8d5e9f9c5768f 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <types/compression.h>
 
+extern unsigned int compress_min_idle;
+
 int comp_append_type(struct comp *comp, const char *type);
 int comp_append_algo(struct comp *comp, const char *algo);
 
@@ -40,6 +42,7 @@ int identity_reset(struct comp_ctx *comp_ctx);
 int identity_end(struct comp_ctx **comp_ctx);
 
 
+
 #ifdef USE_ZLIB
 extern long zlib_used_memory;
 
index 1fe270894bf431a79dfe10ad5b9ca1cbf96451a6..d173e65fa0eb659eb1072aae8bfe1fd3f5ff708c 100644 (file)
@@ -887,6 +887,20 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
                }
                global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
        }
+       else if (!strcmp(args[0], "maxcompcpuusage")) {
+               if (*(args[1]) == 0) {
+                       Alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+               compress_min_idle = 100 - atoi(args[1]);
+               if (compress_min_idle < 0 || compress_min_idle > 100) {
+                       Alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+}
+
        else if (!strcmp(args[0], "ulimit-n")) {
                if (global.rlimit_nofile != 0) {
                        Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
index 2dc893aa56e0cc363a62f8f33836e5046e811b0e..0459aa3015ad7fb8536f11dac5d847c5a343fb95 100644 (file)
@@ -51,6 +51,7 @@ long zlib_used_memory = 0;
 
 #endif
 
+unsigned int compress_min_idle = 0;
 static struct pool_head *pool_comp_ctx = NULL;
 
 
@@ -560,21 +561,19 @@ int deflate_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag)
        out_len = (out->size - buffer_len(out)) - strm->avail_out;
        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.tune.comp_maxlevel) {
-                       /* increase level */
-                       comp_ctx->cur_lvl++ ;
+       /* compression limit */
+       if ((global.comp_rate_lim > 0 && (read_freq_ctr(&global.comp_bps_out) > global.comp_rate_lim)) ||    /* rate */
+          (idle_pct < compress_min_idle)) {                                                                     /* idle */
+               /* 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.tune.comp_maxlevel) {
+               /* increase level */
+               comp_ctx->cur_lvl++ ;
+               deflateParams(&comp_ctx->strm, comp_ctx->cur_lvl, Z_DEFAULT_STRATEGY);
        }
 
        return out_len;
index 8588b50e5f4550a1da3b9471dc2da0369fa64d0a..e5b0fb613e370bdada6689c33e11d5b8a3ba3d04 100644 (file)
@@ -2099,6 +2099,10 @@ int select_compression_response_header(struct session *s, struct buffer *res)
                if (read_freq_ctr(&global.comp_bps_in) > global.comp_rate_lim)
                        goto fail;
 
+       /* limit cpu usage */
+       if (idle_pct < compress_min_idle)
+               goto fail;
+
        /* initialize compression */
        if (s->comp_algo->init(&s->comp_ctx, global.tune.comp_maxlevel) < 0)
                goto fail;