欢迎您, 来到 宁时修博客.^_^

Nginx--04 Nginx限制客户端IP访问连接---官方模块用法解释

2019/01/09 言则行 Nginx 608
Nginx限制客户端IP访问连接

一、简介

    nginx可以通过 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 两个模块配置来限制ip在同一时间段的访问次数。

    先来了解官方对这两个模块定义与使用示例,然后再使用。


二、ngx_http_limit_conn_module模块

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

    该模块用于限制每个已定义 key 的连接数,特别是单个IP地址的连接数。

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


    指令:

Syntax:limit_conn zone number;
Default:—    
Context:http, server, location

    为给定的键值设置共享内存区域和允许的最大连接数。当超过此限制时,服务器将返回错误以响应请求。例如:

    配置示例:一次只允许每个IP地址一个连接

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    # 定义一个名为addr的limit_req_zone用来存储session,大小是10M内存,
    # 以$binary_remote_addr 为key。

    server {

        location /download/ {
            limit_conn addr 1;  # 连接数限制
            # 设置给定键值的共享内存区域和允许的最大连接数。超出此限制时,服务器将返回503(服务临时不可用)错误
            # 如果区域存储空间不足,服务器将返回503(服务临时不可用)错误
        }

    在HTTP/2 和SPDY,每个并发请求被视为是一个单独的连接。


    有几个 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;   #单个客户端ip与服务器的连接数
    limit_conn perserver 100;  #限制与服务器的总连接数
}

    当且仅当 limit_conn 当前级别没有指令时,这些指令才从前一级继承 。


    为服务器限制连接数的情况设置所需的日志记录级别:

Syntax:limit_conn_log_level info | notice | warn | error;
Default:limit_conn_log_level error;
Context:http, server, location  
该指令出现在0.8.18版本中


    设置要响应拒绝的请求而返回的状态代码:

Syntax:limit_conn_status code;
Default:limit_conn_status 503;
Context:http, server, location
该指令出现在1.3.15版本中


    设置共享内存区域的参数,该区域将保留各种键的状态。特别是,状态包括当前的连接数。该key可以包含文本,变量及其组合。具有空键值的请求不计算在内。

Syntax:limit_conn_zone key zone=name:size;
Default:—    
Context:http

    注:在1.7.6版之前,一个 key可能只包含一个变量。


    用法示例:

limit_conn_zone $binary_remote_addr zone=addr:10m;

    在这里,客户机IP地址用作key。注意,这里使用的不是$remote_addr,而是$binary_remote_addr变量。$remote_addr变量的大小可以从7到15个字节不等。存储状态在32位平台上占用32或64字节的内存,在64位平台上占用64字节的内存。$binary_remote_addr变量的大小对于IPv4地址始终为4字节,对于IPv6地址始终为16字节。在32位平台上,存储状态始终占用32或64个字节,在64位平台上则占用64个字节。一个兆字节区域可以保持大约32000个32字节的状态或大约16000个64字节的状态。如果区域存储耗尽,服务器将向所有进一步的请求返回错误。


Syntax:limit_zone name $variable size;
Default:—    
Context:http

    该指令在1.1.8版本中已过时,在1.7.6版本中已删除。应使用具有更改语法的等效limit_conn_zone指令:

limit_conn_zone $variable zone=name: size;



三、ngx_http_limit_req_module模块

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

    ngx_http_limit_req_module模块(0.7.21)用于限制每一个定义的key的请求的处理速率,特别是从一个单一的IP地址的请求的处理速率。使用“漏桶(leaky bucket)”方法进行限制。


    指令:

Syntax:limit_req zone=name [burst=number] [nodelay | delay=number];
Default:—    
Context:http, server, location

    设置共享内存区域和请求的最大突发大小。如果请求速率超过为区域配置的速率,则会延迟其处理,以便以定义的速率处理请求。过多的请求会被延迟,直到它们的数量超过最大突发大小,在这种情况下,请求会因错误而终止。默认情况下,最大突发大小等于零。例如:

    配置示例:平均每秒允许不超过1个请求,突发不超过5个请求。

http { 
    limit_req_zone $binary_remote_addr zone = one:10m rate = 1r / s; 
  

  # 1、$binary_remote_addr:是$remote_addr(客户端IP)的二进制格式,固定占用4个字节,而$remote_addr按照字符串存储,占用7-15个字节,用$binary_remote_addr可以节省空间。这样1M的内存可以保存大约16000个64字节的记录。
    # 2、zone:区域名称,可自定义,这里写的是one,分配内存空间大小为10m,,用来存储会话(二进制客户端IP),如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回 503 (Service Temporarily Unavailable)错误。
    # 3、rate:平均处理的请求数,这里定义的是每秒不能超过每秒1个。也可以设置为每分钟处理请求数(r/m),其值必须是整数。如果限制两秒钟一个请求,可以设置成30r/m
    
    # 这里的意思是:定义一个名为one的limit_req_zone用来存储session,大小是10M内存,  
  # 以$binary_remote_addr 为key,限制平均每秒的请求为1个,


    server { 
        ... 
        location / search / { 
            limit_req zone = one burst = 5; 
            
            #限制每ip每秒不超过1个请求,漏桶数burst为5,也就是缓冲队列.
            #nodelay,如果不设置该选项,严格使用平均速率限制请求数,超过的请求被延时处理.
            #举个例子:
            #设置rate=20r/s 每秒请求数为20个,漏桶数burst为5个,
            #brust的意思就是,如果第1秒,2,3,4秒请求为19个,第5秒的请求为25个是被允许的,可以理解为20+5
            #但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误.
            #如果区域存储空间不足,服务器将返回503(服务临时不可用)错误 
            #速率在每秒请求中指定(r/s)。如果需要每秒少于一个请求的速率,则以每分钟的请求(r/m)指定。
        }


    如果不希望在请求受限的情况下延迟过多请求,则应使用nodelay参数:

limit_req zone = one burst = 5 nodelay;

    delay(延迟)参数指定一个界限,过度请求成为延迟。默认值为零,即所有过多的请求都被延迟。

    nodelay:对用户发起的请求不做延迟处理,而是立即处理。例如定义了rate=20r/s,即每秒钟只处理20个请求。如果同一时刻有22个请求,若设置了nodelay,则会立刻处理这22个请求。若没有设置nodelay,则会严格执行rate=20r/s的配置,即只处理20个请求,然后下一秒钟再处理另外2个请求。直观的看就是页面数据卡了,过了一秒后才加载出来。


    有几个limit_req指令。例如,以下配置将限制来自单个IP地址的请求的处理速率,同时限制虚拟服务器的请求处理速率:

limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
limit_req_zone $server_name zone=perserver:10m rate=10r/s;

server {
    ...
    limit_req zone=perip burst=5 nodelay;  #漏桶数为5个,也就是队列数.nodelay:不启用延迟
    limit_req zone=perserver burst=10;  #限制nginx的处理速率为每秒10个
}

    当且仅当 limit_req 当前级别没有指令时,这些指令才从前一级继承 。


    为服务器由于速率超过或延迟请求处理而拒绝处理请求的情况设置所需的日志记录级别。延迟的日志记录级别比拒绝的日志记录级别低一点;例如,如果指定了“limit_req_log_level notice”,则使用info级别记录延迟。

Syntax:limit_req_log_level info | notice | warn | error;
Default:limit_req_log_level error;
Context:http, server, location
该指令出现在0.8.18版本中


      设置要响应拒绝的请求而返回的状态代码。

Syntax:limit_req_status code;
Default:limit_req_status 503;
Context:http, server, location
该指令出现在1.3.15版本中

  

    设置共享内存区域的参数,该区域将保留各种键的状态。特别是,状态存储当前的过多请求数。该key可以包含文本,变量及其组合组合。具有空键值的请求不计算在内。

Syntax:limit_req_zone key zone=name:size rate=rate [sync];
Default:—    
Context:http

      注:在1.7.6版之前,一个 key可能只包含一个变量。


    用法示例:

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

    在这里,状态保存在一个10m字节的区域“one”中,并且该区域的平均请求处理速率不能超过每秒1个请求。


    客户机IP地址用作key。注意,这里使用的不是$remote_addr,而是$binary_remote_addr变量。$binary_remote_addr变量的大小对于IPv4地址始终为4字节,对于IPv6地址始终为16字节。存储状态在32位平台上总是占据64个字节,在64位平台上总是占据128个字节。一个兆字节区域可以保持大约16000个64字节的状态或大约8000个128字节的状态。


    如果区域存储耗尽,则删除最近最少使用的状态。即使在此之后无法创建新状态,该请求也会因错误而终止。

    速率以每秒请求数(r/s)指定。如果所需的速率小于每秒一个请求,则在每分钟请求(r/m)中指定。例如,每秒半请求是30r/m。


    sync(同步)参数在共享内存区域启用同步。

    注:该参数作为商业订阅提供


点赞
说说你的看法

所有评论: (0)

# 加入组织

1、用手机QQ扫左侧二维码

2、搜Q群:1058582137

3、点击 宁时修博客交流群