13

我想使用 nginx 进行速率限制和缓存。

nginx 以什么顺序应用它们?换句话说,它是仅限制对上游服务器的请求还是所有请求(包括缓存 HIT)?

如何更改此顺序?我认为它可以通过有两个server上下文来改变。因此,例如,on oneserver执行缓存。它具有server作为上游的第二个上下文。第二个限制对“真实”上游的请求。但这可能不是最有效的方法......

4

3 回答 3

2

请求处理

Nginx 请求处理是通过许多不同的阶段完成的,每个阶段都有一个或多个处理程序。模块可以注册以在特定阶段运行。

http://www.nginxguts.com/phases/ http://nginx.org/en/docs/dev/development_guide.html#http_phases

速率限制

ngx_http_limit_req_module预访问阶段应用速率限制。从ngx_http_limit_req_module.c

h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);

缓存

缓存是稍后完成的,我认为是在内容阶段。

通过查看代码或文档,我无法完全弄清楚这一点。但我能够通过调试构建来证明这一点。我的配置有速率限制每秒 1 个请求,并启用缓存。请参阅我的日志中的以下摘录。

缓存请求

...
2020/08/01 11:11:07 [debug] 17498#0: *7 http header done
2020/08/01 11:11:07 [debug] 17498#0: *7 rewrite phase: 0
2020/08/01 11:11:07 [debug] 17498#0: *7 test location: "/"
2020/08/01 11:11:07 [debug] 17498#0: *7 using configuration "=/"
2020/08/01 11:11:07 [debug] 17498#0: *7 http cl:-1 max:1048576
2020/08/01 11:11:07 [debug] 17498#0: *7 rewrite phase: 2
2020/08/01 11:11:07 [debug] 17498#0: *7 post rewrite phase: 3
2020/08/01 11:11:07 [debug] 17498#0: *7 generic phase: 4
2020/08/01 11:11:07 [debug] 17498#0: *7 http script var: ....
2020/08/01 11:11:07 [debug] 17498#0: shmtx lock
2020/08/01 11:11:07 [debug] 17498#0: shmtx unlock
2020/08/01 11:11:07 [debug] 17498#0: *7 limit_req[0]: 0 0.000
2020/08/01 11:11:07 [debug] 17498#0: *7 generic phase: 5
2020/08/01 11:11:07 [debug] 17498#0: *7 access phase: 6
2020/08/01 11:11:07 [debug] 17498#0: *7 access phase: 7
2020/08/01 11:11:07 [debug] 17498#0: *7 post access phase: 8
2020/08/01 11:11:07 [debug] 17498#0: *7 generic phase: 9
2020/08/01 11:11:07 [debug] 17498#0: *7 generic phase: 10
2020/08/01 11:11:07 [debug] 17498#0: *7 http init upstream, client timer: 0
2020/08/01 11:11:07 [debug] 17498#0: *7 http cache key: "http://127.0.0.1:9000"
2020/08/01 11:11:07 [debug] 17498#0: *7 http cache key: "/"
2020/08/01 11:11:07 [debug] 17498#0: *7 add cleanup: 00005609F7C51578
2020/08/01 11:11:07 [debug] 17498#0: shmtx lock
2020/08/01 11:11:07 [debug] 17498#0: shmtx unlock
2020/08/01 11:11:07 [debug] 17498#0: *7 http file cache exists: 0 e:1
2020/08/01 11:11:07 [debug] 17498#0: *7 cache file: "/home/poida/src/nginx-1.15.6/objs/cache/157d4d91f488c05ff417723d74d65b36"
2020/08/01 11:11:07 [debug] 17498#0: *7 add cleanup: 00005609F7C46810
2020/08/01 11:11:07 [debug] 17498#0: *7 http file cache fd: 12
2020/08/01 11:11:07 [debug] 17498#0: *7 read: 12, 00005609F7C46890, 519, 0
2020/08/01 11:11:07 [debug] 17498#0: *7 http upstream cache: 0
2020/08/01 11:11:07 [debug] 17498#0: *7 http proxy status 200 "200 OK"
2020/08/01 11:11:07 [debug] 17498#0: *7 http proxy header: "Server: SimpleHTTP/0.6 Python/3.8.5"
2020/08/01 11:11:07 [debug] 17498#0: *7 http proxy header: "Date: Sat, 01 Aug 2020 01:11:03 GMT"
2020/08/01 11:11:07 [debug] 17498#0: *7 http proxy header: "Content-type: text/html; charset=utf-8"
2020/08/01 11:11:07 [debug] 17498#0: *7 http proxy header: "Content-Length: 340"
2020/08/01 11:11:07 [debug] 17498#0: *7 http proxy header done
2020/08/01 11:11:07 [debug] 17498#0: *7 http file cache send: /home/poida/src/nginx-1.15.6/objs/cache/157d4d91f488c05ff417723d74d65b36
2020/08/01 11:11:07 [debug] 17498#0: *7 posix_memalign: 00005609F7C46DC0:4096 @16
2020/08/01 11:11:07 [debug] 17498#0: *7 HTTP/1.1 200 OK
...

速率限制请求

...
2020/08/01 11:17:04 [debug] 17498#0: *10 http header done
2020/08/01 11:17:04 [debug] 17498#0: *10 rewrite phase: 0
2020/08/01 11:17:04 [debug] 17498#0: *10 test location: "/"
2020/08/01 11:17:04 [debug] 17498#0: *10 using configuration "=/"
2020/08/01 11:17:04 [debug] 17498#0: *10 http cl:-1 max:1048576
2020/08/01 11:17:04 [debug] 17498#0: *10 rewrite phase: 2
2020/08/01 11:17:04 [debug] 17498#0: *10 post rewrite phase: 3
2020/08/01 11:17:04 [debug] 17498#0: *10 generic phase: 4
2020/08/01 11:17:04 [debug] 17498#0: *10 http script var: ....
2020/08/01 11:17:04 [debug] 17498#0: shmtx lock
2020/08/01 11:17:04 [debug] 17498#0: shmtx unlock
2020/08/01 11:17:04 [debug] 17498#0: *10 limit_req[0]: -3 0.707
2020/08/01 11:17:04 [error] 17498#0: *10 limiting requests, excess: 0.707 by zone "mylimit", client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "localhost:8080"
2020/08/01 11:17:04 [debug] 17498#0: *10 http finalize request: 503, "/?" a:1, c:1
2020/08/01 11:17:04 [debug] 17498#0: *10 http special response: 503, "/?"
2020/08/01 11:17:04 [debug] 17498#0: *10 http set discard body
2020/08/01 11:17:04 [debug] 17498#0: *10 HTTP/1.1 503 Service Temporarily Unavailable
...

对于速率受限的请求,处理在服务器尝试生成内容或检查缓存之前停止。

TL;博士; 在缓存之前首先应用速率限制。

于 2020-08-01T01:23:49.547 回答
-1

NGINX

Nginx 限速器是如何工作的

NGINX 速率限制使用漏桶算法,该算法广泛用于电信和分组交换计算机网络中,以处理带宽受限时的突发性。类比是一个桶,水从顶部倒入,从底部漏出;如果倒水的速度超过漏水的速度,水桶就会溢出。在请求处理方面,水代表来自客户端的请求,桶代表一个队列,其中请求根据先进先出 (FIFO) 调度算法等待处理。漏水代表请求退出缓冲区供服务器处理,溢出代表请求被丢弃且从未服务。

从我的一台服务器添加配置快照:

在此处输入图像描述

ngx_http_limit_conn_module模块用于限制每个定义的键的连接数,特别是来自单个 IP 地址的连接数。

并非所有连接都被计算在内。只有当服务器正在处理一个请求并且已经读取了整个请求标头时,才计算一个连接。

所以基本上你可以为实际和所有其他单独的虚拟服务器做两个设置。

通过限制IP 通过限制连接

可能有几个 limit_conn 指令。例如,以下配置将限制每个客户端 IP 与服务器的连接数,同时限制与虚拟服务器的连接总数:

以下是相同的示例

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;

server {
    ...
    limit_conn perip 10;
    limit_conn perserver 100;
}

一起前行!

达尔潘

您也可以在此处找到详细示例和说明

于 2020-08-01T08:07:05.763 回答
-1

如果您有网络负载均衡器,那么您必须在两台服务器上实现速率和缓存。

速率限制是这样的。

location /login/ {
    limit_req zone=mylimit burst=20;
 
    proxy_pass http://my_upstream;
}

Burst 参数定义了客户端可以发出多少请求超过区域指定的速率(对于我们的示例 mylimit 区域,速率限制为每秒 10 个请求,或每 100 毫秒 1 个请求)。一个在前一个请求后 100 毫秒内到达的请求被放入队列,这里我们将队列大小设置为 20。

这意味着如果 21 个请求同时从给定 IP 地址到达,NGINX 会立即将第一个请求转发到上游服务器组,并将剩余的 20 个放入队列中。然后它每 100 毫秒转发一个排队的请求,并且仅当传入的请求使排队的请求数超过 20 时才向客户端返回 503。现在,如果您在一台服务器上限制评级,那么两个后续请求将发送到不同的服务器会有问题。所有缓存变量也需要同步。您需要 Redis 或持久存储来进行缓存。

https://www.nginx.com/blog/rate-limiting-nginx/

于 2020-07-31T17:24:15.647 回答