[nginx] Limit req: "delay=" parameter.

Maxim Dounin mdounin at mdounin.ru
Wed Nov 21 17:19:13 UTC 2018


details:   http://hg.nginx.org/nginx/rev/d6ca744c727e
branches:  
changeset: 7399:d6ca744c727e
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Wed Nov 21 18:56:50 2018 +0300
description:
Limit req: "delay=" parameter.

This parameter specifies an additional "soft" burst limit at which requests
become delayed (but not yet rejected as it happens if "burst=" limit is
exceeded).  Defaults to 0, i.e., all excess requests are delayed.

Originally inspired by Vladislav Shabanov
(http://mailman.nginx.org/pipermail/nginx-devel/2016-April/008126.html).
Further improved based on a patch by Peter Shchuchkin
(http://mailman.nginx.org/pipermail/nginx-devel/2018-October/011522.html).

diffstat:

 src/http/modules/ngx_http_limit_req_module.c |  32 +++++++++++++++++++--------
 1 files changed, 22 insertions(+), 10 deletions(-)

diffs (93 lines):

diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c
--- a/src/http/modules/ngx_http_limit_req_module.c
+++ b/src/http/modules/ngx_http_limit_req_module.c
@@ -44,7 +44,7 @@ typedef struct {
     ngx_shm_zone_t              *shm_zone;
     /* integer value, 1 corresponds to 0.001 r/s */
     ngx_uint_t                   burst;
-    ngx_uint_t                   nodelay; /* unsigned  nodelay:1 */
+    ngx_uint_t                   delay;
 } ngx_http_limit_req_limit_t;
 
 
@@ -499,12 +499,12 @@ ngx_http_limit_req_account(ngx_http_limi
 
     excess = *ep;
 
-    if (excess == 0 || (*limit)->nodelay) {
+    if ((ngx_uint_t) excess <= (*limit)->delay) {
         max_delay = 0;
 
     } else {
         ctx = (*limit)->shm_zone->data;
-        max_delay = excess * 1000 / ctx->rate;
+        max_delay = (excess - (*limit)->delay) * 1000 / ctx->rate;
     }
 
     while (n--) {
@@ -544,11 +544,11 @@ ngx_http_limit_req_account(ngx_http_limi
 
         ctx->node = NULL;
 
-        if (limits[n].nodelay) {
+        if ((ngx_uint_t) excess <= limits[n].delay) {
             continue;
         }
 
-        delay = excess * 1000 / ctx->rate;
+        delay = (excess - limits[n].delay) * 1000 / ctx->rate;
 
         if (delay > max_delay) {
             max_delay = delay;
@@ -875,9 +875,9 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c
 {
     ngx_http_limit_req_conf_t  *lrcf = conf;
 
-    ngx_int_t                    burst;
+    ngx_int_t                    burst, delay;
     ngx_str_t                   *value, s;
-    ngx_uint_t                   i, nodelay;
+    ngx_uint_t                   i;
     ngx_shm_zone_t              *shm_zone;
     ngx_http_limit_req_limit_t  *limit, *limits;
 
@@ -885,7 +885,7 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c
 
     shm_zone = NULL;
     burst = 0;
-    nodelay = 0;
+    delay = 0;
 
     for (i = 1; i < cf->args->nelts; i++) {
 
@@ -915,8 +915,20 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c
             continue;
         }
 
+        if (ngx_strncmp(value[i].data, "delay=", 6) == 0) {
+
+            delay = ngx_atoi(value[i].data + 6, value[i].len - 6);
+            if (delay <= 0) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "invalid delay value \"%V\"", &value[i]);
+                return NGX_CONF_ERROR;
+            }
+
+            continue;
+        }
+
         if (ngx_strcmp(value[i].data, "nodelay") == 0) {
-            nodelay = 1;
+            delay = NGX_MAX_INT_T_VALUE / 1000;
             continue;
         }
 
@@ -956,7 +968,7 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c
 
     limit->shm_zone = shm_zone;
     limit->burst = burst * 1000;
-    limit->nodelay = nodelay;
+    limit->delay = delay * 1000;
 
     return NGX_CONF_OK;
 }


More information about the nginx-devel mailing list