我想使用nginx进行速率限制和缓存。
nginx以哪种顺序应用它们?换句话说,它是仅限制对上游服务器的请求还是所有请求(包括缓存HIT')?
如何更改此订单?我认为可以通过两个server
上下文来改变它。因此,例如,在一个server
上执行缓存。它有第二个server
上下文作为上游。第二个限制了对"真实"上游。但这可能不是最有效的方式......
答案 0 :(得分:1)
Nginx请求处理是通过许多不同的阶段完成的,每个阶段都有一个或多个处理程序。模块可以注册以在特定阶段运行。
http://www.nginxguts.com/phases/ http://nginx.org/en/docs/dev/development_guide.html#http_phases
费率限制由body {
padding-top: 88px;
}
在预访问阶段中应用。来自ngx_http_limit_req_module.c:
ngx_http_limit_req_module
稍后进行缓存,我在内容阶段认为。
通过查看代码或文档,我无法完全弄清这一点。但是我能够通过调试版本来演示这一点。我的配置在打开缓存的情况下每秒限制1个请求的速率。请参阅我的日志中的以下摘录。
缓存的请求
h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
费率限制请求
...
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
...
对于速率受限的请求,处理将在服务器尝试生成内容或检查缓存之前停止。
TL; DR;速率限制是在缓存之前首先应用的。
答案 1 :(得分:0)
如果您具有网络负载平衡器,则必须在两个服务器上都实现速率和缓存。
速率限制是这样的。
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或永久存储进行缓存。
答案 2 :(得分:0)
NGINX
How does Nginx rate limiter works
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;
}
一起前进!
大潘