Nginx下limit_req模块限制访问频次

最近实际开发过程中,发现部分服务资源访问503 Service Temporarily Unavailable,查找后证实是在对nginx做了限速以后,限速做的太低了超过访问次数直接拒绝访问返回503错误。

nginx 可以使用ngx_http_limit_req对服务器资源请求进行限制。

该模块使用 漏斗算法(Leaky Bucket),该算法有两种处理方式Traffic Shaping和Traffic Policing

在桶满水之后,常见的两种处理方式为:
1.暂时拦截住上方水的向下流动,等待桶中的一部分水漏走后,再放行上方水。
2.溢出的上方水直接抛弃。

将水看作网络通信中数据包的抽象,则方式1起到的效果称为Traffic Shaping,方式2起到的效果称为Traffic Policing
由此可见,Traffic Shaping的核心理念是"等待",Traffic Policing的核心理念是"丢弃"。它们是两种常见的流速控制方法

nginx中该模块的使用配置示例

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
 
server {
    location /search/ {
        limit_req zone=one burst=5 nodelay;
    }

第一段配置

第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址
第二个参数:zone=one:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息
第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有比如30r/m的

第二段配置


第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应
第二个参数:burst=5,这个配置的意思是设置一个大小为5的缓冲区当有大量请求过来时,超过了访问频次限制的请求可以先放到这个缓冲区内
第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队

接下去举例来看, 更为直观点。

案例1:
设置条件: 速率qps=1, 峰值burst=5, 延迟请求,即没有nodelay参数
效果: 严格按照漏桶速率qps=1处理每秒请求,由于burst=5,所以当一秒内接受到的请求数载1到5之间的时候,没有被处理的请求,会被暂时挂起,相当于存储在漏桶中,一共能存储5个;当前1秒处理一个, 剩下的会被延迟处理
     如果请求数超过了burst的限制,则会直接返回503;客户端只要控制并发在峰值burst内,就不会触发limit_req_error_log

案例2:
设置条件:速率qps=1, 峰值burst=5, 不延迟请求, 即有nodelay参数
效果:加了nodelay之后,漏桶控制一段时长内的平均qps = 漏桶速率,但是允许瞬时的峰值qps 大于 漏桶qps。 峰值是最高的qps=brust + qps - 1
     比如一开始的时候,如果一下子过来了5个请求,虽然qps=1,但是由于有burst=5,瞬时的峰值能够到达qps=5, 这个5个请求能够同时被处理并返回 ;但是由于设定了漏桶速率qps=1,所以在接下去的5秒时间段内,不能再接受其他请求 

猜你喜欢

转载自blog.csdn.net/harleylau/article/details/79987376