登录 |  注册 |  繁體中文


使用Nginx限制并发及访问频次

分类: 服务器相关 颜色:橙色 默认  字号: 阅读(1921) | 评论(0)

先贴一下官方wiki介绍:

http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html

ngx_http_limit_conn_module 主要限制并发数

ngx_http_limit_req_module 主要限制请求频率, 此模块能通过特定的客户端标识(如IP,UA等)来限制客户端在一定时间内的访问频次;

如果是一瞬间的并发访问,那么我们就需要限制一秒之内的并发连接数,此时就需要用到第一个配置,如果一个IP疯狂的调用接口,如:页面上写个for循环一直刷请求,可能导致将服务器的带宽耗尽,此时就需要用到第二个配置

 

一、 ngx_http_limit_conn_module 模块

限制并发连接数

Syntax: limit_conn_zone key zone=name:size;
Default:
Context: http
示例:limit_conn_zone $limitIp zone=maxConnLimitZone:10m;
 
Syntax: limit_conn zone number;
Default:
Context: http, server, location
示例:limit_conn one 20;          #连接数限制
 

一、ngx_http_limit_req_module 模块

limit_req_zone 和 limit_req

首先来看一下limit_req_zone的配置,该指令必须放置在http的范围内配置;

Syntax: limit_req_zone $variable zone = name : size rate = rate
Default:  
Context: http

示例: limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

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

最终NGINX会把所有的参数统一为按秒为单位。所以10r/s和600r/m效果是一样的

指令limit_req 

Syntax: limit_req zone = name [ burst = number ] [ nodelay ]
Default:  
Context: http
server
location

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

 

示例详解:
  • limit_req zone=req_zone;
    • 严格依照在limti_req_zone中配置的rate来处理请求
    • 超过rate处理能力范围的,直接drop
    • 表现为对收到的请求无延时
  • limit_req zone=req_zone burst=5;
    • 依照在limti_req_zone中配置的rate来处理请求
    • 同时设置了一个大小为5的缓冲队列,在缓冲队列中的请求会等待慢慢处理
    • 超过了burst缓冲队列长度和rate处理能力的请求被直接丢弃
    • 表现为对收到的请求有延时
  • limit_req zone=req_zone burst=5 nodelay;
    • 依照在limti_req_zone中配置的rate来处理请求
    • 同时设置了一个大小为5的缓冲队列,当请求到来时,会爆发出一个峰值处理能力,对于峰值处理数量之外的请求,直接丢弃
    • 在完成峰值请求之后,缓冲队列不能再放入请求。如果rate=10r/m,且这段时间内没有请求再到来,则每6 s 缓冲队列就能回复一个缓冲请求的能力,直到回复到能缓冲5个请求位置。

 

三、实列配置:

http {
      ## 这里取得原始用户的IP地址,没走CDN/SLB的,给到$remote_addr
    map $http_x_forwarded_for  $clientRealIp {
          $remote_addr; 
         default $http_x_forwarded_for;
        
    }
    #设置IP白名单,对内部的IP不设限
    map $clientRealIp $limitIp{
        default $clientRealIp;
        xx.xx.xx.xx "";
    }    

    limit_conn_status 429; 
    limit_conn_zone $limitIp zone = myConnLimit : 10m;
    limit_conn_log_level notice;

    #限制请求数,并返回429状态;
    limit_req_status 429;
    limit_req_zone $limitIp zone=myReqLimit:10m rate=1r/s; #限制每秒一个请求  
    limit_req_log_level notice;  
    
    server {
        location & nbsp;
        ^ ~ / download / {
            
            limit_conn myConnLimit 2; #一瞬间访问的时候,只会有2个IP能得到响应,后面的IP直接就返回503状态。
            limit_req zone=myReqLimit burst=5 delay; 
        }
    }
} 



姓 名: *
邮 箱:
内 容: *
验证码: 点击刷新 *   

回到顶部