极客专栏《Nginx核心知识100讲》55-56小节的笔记
55 | preaccess阶段:对连接做限制的limit_conn模块
在preaccess阶段限制用户并发连接数的limit_conn模块。上一节讲到匹配location,匹配到之后,接下来的模块往往它们的指令都可以出现在location 中。preaccess阶段中有两个模块limit_req、limit_conn。一个是用来限制每秒处理请求数,一个是限制并发连接数。
问题:如何限制每个客户端的并发链接数
image.png使用了共享内存。接下来会看到它用到了一个zone指令。所有的nginx的 zone指令都是在分配共享内存。
限制有效性取决于关键字的设计。比如我们限制客户端的并发连接数。而我们的nginx之前有SLB,通过realip模块取到用户真实ip。根据这个ip再来做并发连接数限制。
limit_conn指令
image.pnglimit_conn指令的 number是可以允许并发连接数。这些并发连接数是根据key(往往取自于用户IP,remote_addr)来定的。
image.png例子
image.png当nginx作为资源服务器为用户提供使用时,限制用户发起的并发连接数是比较常用的功能。limit_conn模块设计好它的key是个关键。
留言问题
1.rate这个指标设置多大合适呢,有没有什么参考值,另外burst这个桶设置多大合适呢
作者回复
rate需要匹配产品设计策略,或者结合运营收入和运维带宽成本来分析。burst设置多大合适,只与产品设计和场景有关,没有统一参考值的。
2.在limit_conn_zone $binary_remote_addr zone=perip:10m;配置中,如果共享区域内存耗尽,Nginx文档上说回对所有请求都返回错误,那么,如何监测此类情况呢
作者回复
可以使用第38课介绍过的slab_stat,监控fails指标以及共享内存slab已用量
3.多台nginx 的时候,如何限制并发连接数?
作者回复
跨主机通讯?nginx模块并不支持,你可以考虑openresty+redis的方案,其中redis集群作中心存储,key是客户端标识,value是当前并发连接数。
4.请问在您的例子里,严格的来讲,是第一个请求还未结束,第二个請求又发起的时候,并发连接数为2对吗?
作者回复
对的
56 | preaccess阶段:对请求做限制的limit_req模块
问题:如何限制每个客户端的每秒处理请求数?
image.pngLeaky Bucket
image.png突发性的流量,右上角那副图。横轴是以秒为单位,纵轴是每秒传输的流量。前两秒中都是12Mbps,2-7秒钟没有流量,7-10每秒2Mbps。这种突发流量使用了Leaky Bucket以后就变成了右下角的那副图了,每秒3Mbps。累加起来的值跟右上图是一致的。左图形象的说明了这个操作。
当盆满了还在滴水就立刻给用户返回503。但没有满的时候,下面的流速达到最大化,水滴就存在盆里。用户的请求就在变慢,而不是被拒绝。
limit_req指令
image.pngburst=number 盆里可以容纳多少个请求。nodelay意义,当设置了nodelay,burst里面的请求就会立即返回错误。
image.png例子
image.png image.pngrate=2r/m。每分钟处理两个请求。之所以加这样的限制是为了更快的看到效果。
image.png image.png image.pnglimit_conn跟limit_req 都打开之后看下,返回的是500还是503?limit_req 是在limit_conn之前。所以,limit_req 已经拒绝用了limit_conn就得不到执行。
留言问题
- 我对生效范围是全部work进程还不是很理解。
这样问您:比如总共有10个模块被编译进了二进制文件,nginx启动时,先启动master进程,master进程然后启动多个work进程。
这多个work进程的工作任务是同样的吗?或者他们分别负责不同的工作,比如第一个work负责前五个模块的工作,第二个work负责后五个的工作?
作者回复
每个worker进程是等效的,功能完全相同。多worker进程的意义在于使用多CPU,第5部分内容会详细介绍。由内核调度worker进程,决定把哪些连接交给哪个worker进程处理。
2.请问怎么获取post请求中的参数值呢,我想通过post请求参数进行限流。:-)
作者回复
根据请求中的body么? 这样不行,你没办法利用preaccess阶段的模块了,因为这些模块工作时,只能确保接收到完整的url参数和http header,是否接收到完整的body中的form完全无法保证
3.在视频5分钟作用的时候,您的配置文件是2r/m,然后用curl limit.taohui.tech连续发了2条请求,然后第二条请求返回503,为啥不是第三条返回503,第二条就503了呢?我的理解里面发第2条请求的时候是满足2r/m的
作者回复
可能是视频剪辑时剪辑掉啦,你的理解是对的:-)
3.老师你好 WAF这种过滤规则在哪个阶段
作者回复
多数lua waf都是在access阶段工作的
4.限制请求和连接的ip是指tcp层的请求的ip吧,如果ngnix前面加了WAF和负载均衡,对这个有没有影响呢?
作者回复
不是哦,你可以再看一下第50课里的realip模块,这个ip可以不是tcp层中的remote ip,而是http request header中的xforwarded-for或者x-realip头部的内容
5.limit_**指令中的key究竟是什么意思呢?它和限制的数量有什么关系?比如说key是用户ip,limit_conn是2,就表示每个不同的用户只能同时有两个连接到服务器吗?
作者回复
是的
网友评论