谈一谈nginx限制连接与请求的模块

前言

前段时间,所负责的项目疑似被爬虫爬取了;于是考虑从nginx层限制单IP访问频率;查阅相关资料后,发现nginx有两个相关的限制连接和请求的模块:ngx_http_limit_conn_module,ngx_http_limit_req_module;接下来就简单谈一谈这两个模块;

寻根溯源

ngx_http_limit_conn_module

我们先看看,官网http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
如何介绍ngx_http_limit_conn_module模块的,以下为简单翻译:

  • 配置示例
  • 指令
    limit_conn
    limit_conn_dry_run
    limit_conn_log_level
    limit_conn_status
    limit_conn_zone
    limit_zone
  • 嵌入式变量
配置示例
http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    ...

    server {

        ...

        location /download/ {
            limit_conn addr 1;
        }
指令集

limit_conn

语法: limit_conn zone number;
默认值:    —
作用域:    http, server, location

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

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    location /download/ {
        limit_conn addr 1;
    }

每个IP地址只允许一个连接。
HTTP/2SPDY中,每个并发请求都被视为一个单独的连接。
可能有多个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;
}

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

limit_conn_dry_run

语法:limit_conn_dry_run on | off;
默认值:limit_conn_dry_run off;
作用域:http, server, location
该指令出现在版本1.17.6中

启用空运行模式。在此模式下,连接数不受限制,但是,在共享内存区域中,过多连接的数将照常计算。

limit_conn_log_level

语法:limit_conn_log_level info | notice | warn | error;
默认值:limit_conn_log_level error;
作用域:http, server, location
该指令出现在版本 0.8.18中.

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

limit_conn_status

语法:limit_conn_status code;
默认值:limit_conn_status 503;
作用域:http, server, location
该指令出现在版本1.3.15中.

设置状态代码以响应被拒绝的请求。

limit_conn_zone

语法:limit_conn_zone key zone=name:size;
默认值:    —
作用域:http

设置共享内存区域的参数,该参数将保留各种键的状态;特别是,状态包括当前的连接数。键可以包含文本,变量及其组合。键为空的请求不予考虑。
在版本1.7.6之前,键可以只包含一个变量。
用法示例:

limit_conn_zone $binary_remote_addr zone=addr:10m;

在这,客户端的一个IP地址作为一个key,请注意,此处使用$binary_remote_addr变量代替$remote_addr$remote_addr变量的大小可以从7到15个字节不等。 存储状态在32位平台上占用32或64字节的内存,在64位平台上始终占用64字节。 $binary_remote_addr变量的大小对于IPv4地址始终为4个字节,对于IPv6地址始终为16个字节。 在32位平台上,存储状态始终占据32或64字节,在64位平台上,存储状态始终占据64字节。 1M的区域可以保留大约3.2万个32字节状态或大约1.6万个64字节状态。 如果区域存储空间已用完,服务器将把错误返回给所有其他请求。

此外,作为我们的商业订阅的一部分,可以从1.17.7开始使用API​​获取或重置每个此类共享存储区的状态信息

limit_zone

语法:limit_zone name $variable size;
默认值:—
作用域:http

该指令在1.1.8版中已过时,在1.7.6版中已删除。应当使用等效的limit_conn_zone伪指令(其语法已更改)代替:

limit_conn_zone $variable zone=name:size;

嵌入式变量

$limit_conn_status
保留限制连接数(1.17.6)的结果:PASSED,REJECTED或REJECTED_DRY_RUN

ngx_http_limit_req_module

我们继续看看官网 http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
是如何介绍ngx_http_limit_conn_module模块的,以下为简单翻译:

  • 配置示例
  • 指令
    limit_req
    limit_req_dry_run
    limit_req_log_level
    limit_req_status
    limit_req_zone
  • 嵌入式变量
    ngx_http_limit_req_module模块(0.7.21)用于限制每个已定义key的请求处理速率,特别是来自单个IP地址的请求的处理速率。使用“漏斗”方法完成限制。

配置示例

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

    ...

    server {

        ...

        location /search/ {
            limit_req zone=one burst=5;
        }

指令集

limit_req

语法:limit_req zone=name [burst=number] [nodelay | delay=number];
默认值:—
作用域:http, server, location

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

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

server {
    location /search/ {
        limit_req zone=one burst=5;
    }

平均每秒最多允许不超过1个请求,并且突发不超过5个请求
如果不需要在限制请求时延迟过多的请求,则应使用参数nodelay

limit_req zone=one burst=5 nodelay;

delay参数(1.15.7)指定一个限制,在该限制下,过多的请求将被延迟。默认值为零,即所有多余的请求都会延迟。
可能有多个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;
    limit_req zone=perserver burst=10;
}

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

limit_req_dry_run

语法:limit_req_dry_run on | off;
默认值:limit_req_dry_run off;
作用域:http, server, location
该指令出现在1.17.1版中

启用空运行模式。在这种模式下,请求处理速度不受限制,但是,在共享内存区域中,过多请求的数量将照常进行计算。

limit_req_log_level

语法:limit_req_log_level info | notice | warn | error;
默认值:limit_req_log_level error;
作用域:http, server, location
该指令出现在0.8.18版中.

在服务器由于速率超出而拒绝处理请求或延迟请求处理的情况下,设置所需的日志记录级别。延迟的日志级别比拒绝低了一个等级,例如,如果指定了日志级别为 limit_req loglevel notice,延迟的日志级别为info

limit_req_status

语法:limit_req_status code;
默认值:limit_req_status 503;   
作用域:http, server, location
该指令出现在1.3.15版中.

设置状态代码以响应被拒绝的请求

limit_req_zone

语法:limit_req_zone key zone=name:size rate=rate [sync];
默认值:—
作用域:http

设置共享内存区域的参数,该参数将保留各种键的状态。 特别是,状态存储了当前过多请求的数量。 键可以包含文本,变量及其组合。 key值为空的请求不予考虑。
在版本1.7.6之前,键可以只包含一个变量
用法示例:

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

这里,状态保持在10M的区域one中,并且该区域的平均请求处理速率不能超过每秒1个请求。
客户端IP地址用作密钥。 请注意,此处使用$binary_remote_addr变量代替$remote_addr$binary_remote_addr变量的大小对于IPv4地址始终为4个字节,对于IPv6地址始终为16个字节。 存储状态在32位平台上始终占据64字节,在64位平台上始终占据128字节。 一个1M字节的区域可以保留约1.6万个64字节状态或约8000个128字节状态。
如果区域存储已用尽,则删除最近最少使用的状态。如果在此之后仍无法创建新状态,则请求将终止并出现错误
该速率以每秒请求数r/s指定。如果希望速率小于每秒一个请求,则以每分钟请求数r/m来指定。例如,每秒半请求为30r/m
sync参数(1.15.3)启用共享内存区域的同步

嵌入式变量

$limit_req_status
保留限制请求处理速率(1.17.6)的结果:PASSED,DELAYED,REJECTED,DELAYED_DRY_RUN或REJECTED_DRY_RUN

小结

简单来说,如果想要比较准确的限制爬虫等非法请求,尽量两个模块结合使用

你可能感兴趣的:(谈一谈nginx限制连接与请求的模块)