Nginx Rate limiting for HTTPS requests
Maxim Dounin
mdounin at mdounin.ru
Wed May 23 19:34:07 UTC 2018
Hello!
On Wed, May 23, 2018 at 12:58:53AM -0400, rickGsp wrote:
> >>Please show "uname -a", "nginx -V", and "ps -alxww | grep nginx"
> >>output.
>
> #uname -a
> Linux localhost.localdomain 3.10.0-693.11.6.el7.x86_64 #1 SMP Thu Jan 4
> 01:06:37 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
>
> #nginx -V
> nginx version: nginx/1.14.0
> built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
> built with OpenSSL 1.0.2k-fips 26 Jan 2017
[...]
Thank you, I was able to reproduce this.
This indeed seems to be a problem with request rate limiting which
manifests itself when high request rates are used, there are
multiple worker processes, and request processing results in long
delays during event loop iterations (so that's why HTTPS requests
were special).
The problem is that time, as updated by each worker process at the
event loop iteration start, can be different in different workers
due to delays. Moreover, a worker may be in the future relative
to another worker. And this interfered nicely with nginx request
rate limiting logic which trying to be tolerant to time changes.
Quick and dirty patch below. It is expected to work fine on
systems with monotonic clocks available, but may need more work to
handle time changes on systems without monotonic clocks.
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
@@ -398,8 +398,9 @@ ngx_http_limit_req_lookup(ngx_http_limit
ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
ms = (ngx_msec_int_t) (now - lr->last);
+ ms = ngx_max(ms, 0);
- excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
+ excess = lr->excess - ctx->rate * ms / 1000 + 1000;
if (excess < 0) {
excess = 0;
@@ -413,7 +414,7 @@ ngx_http_limit_req_lookup(ngx_http_limit
if (account) {
lr->excess = excess;
- lr->last = now;
+ lr->last += ms;
return NGX_OK;
}
@@ -508,14 +509,15 @@ ngx_http_limit_req_account(ngx_http_limi
now = ngx_current_msec;
ms = (ngx_msec_int_t) (now - lr->last);
+ ms = ngx_max(ms, 0);
- excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
+ excess = lr->excess - ctx->rate * ms / 1000 + 1000;
if (excess < 0) {
excess = 0;
}
- lr->last = now;
+ lr->last += ms;
lr->excess = excess;
lr->count--;
--
Maxim Dounin
http://mdounin.ru/
More information about the nginx
mailing list