Nginx 资源请求限制:链接数/请求速率/宽带

前置条件:

nginx 需要有 ngx_http_limit_conn_modulengx_http_limit_req_module 模块,可以使用命令 2>&1 nginx -V | tr ' ' '\n'|grep limit 检查有没有相应模块,如果没有请重新编译安装这两个模块。

测试版本为:nginx 版本为 1.15+

1. 限制链接数

1.使用 limit_conn_zone 指令定义密钥并设置共享内存区域的参数(工作进程将使用此区域来共享密钥值的计数器)。第一个参数指定作为键计算的表达式。第二个参数 zone 指定区域的名称及其大小:

limit_conn_zone $binary_remote_addr zone=addr:10m;

2.在 location {}, server {} 或者 http {} 上下文中使用 limit_conn 指令来应用限制,第一个参数为上面设定的共享内存区域名称,第二个参数为每个 key 被允许的链接数:

location /download/ {
     limit_conn addr 1;
}

使用 $binary_remote_addr 变量作为参数的时候,是基于 IP 地址的限制,同样可以使用 $server_name 变量进行给定服务器连接数的限制:

http {
    limit_conn_zone $server_name zone=servers:10m;

    server {
        limit_conn servers 1000;
    }
}

2. 限制请求速率

速率限制可用于防止 DDoS,CC 攻击,或防止上游服务器同时被太多请求淹没。该方法基于 leaky bucket 漏桶算法,请求以各种速率到达桶并以固定速率离开桶。在使用速率限制之前,您需要配置 "漏桶" 的全局参数:

  • key - 用于区分一个客户端与另一个客户端的参数,通常是变量
  • shared memory zone - 保留这些密钥状态的区域的名称和大小(即 "漏桶")
  • rate - 每秒请求数(r/s)或每分钟请求数(r/m)("漏桶排空")中指定的请求速率限制。每分钟请求数用于指定小于每秒一个请求的速率。

这些参数使用 limit_req_zone 指令设置。该指令在 http {} 级别上定义 - 这种方法允许应用不同的区域并请求溢出参数到不同的上下文:

http {
    #...

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

使用此配置,将创建大小为 10m 字节,名称为 one 的共享内存区域。该区域保存使用 $binary_remote_addr 变量设置的客户端 IP 地址的状态。请注意,$remote_addr 还包含客户端的 IP 地址,而 $binary_remote_addr 保留更短的 IP 地址的二进制表示。

可以使用以下数据计算共享内存区域的最佳大小:$binary_remote_addr IPv4 地址的值大小为 4 个字节,64 位平台上的存储状态占用 128 个字节。因此,大约 16000 个 IP 地址的状态信息占用该区域的 1m 字节。

如果在 NGINX 需要添加新条目时存储空间耗尽,则会删除最旧的条目。如果释放的空间仍然不足以容纳新记录,NGINX 将返回 503 Service Unavailable 状态代码,状态码可以使用 limit_req_status 指令重新定义。

一旦该区域被设置,你可以使用 NGINX 配置中的任何地方使用 limit_req 指令限制请求速率,尤其是 server {}, location {}http {} 上下文:

http {
    #...

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

    server {
        #...

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

使用如上配置,nginx 在 /search/ 路由下将每秒处理不超过 1 个请求,延迟处理这些请求的方式是总速率不大于设定的速率。NGINX 将延迟处理此类请求,直到 "存储区"(共享存储区 one)已满。对于到达完整存储桶的请求,NGINX 将响应 503 Service Unavailable 错误(当 limit_req_status 未自定义设定状态码时)。

3. 限制宽带

要限制每个连接的带宽,请使用以下 limit_rate 指令:

location /download/ {
    limit_rate 50k;
}

通过此设置,客户端将能够通过单个连接以最高 50k/秒 的速度下载内容。但是,客户端可以打开多个连接跳过此限制。因此,如果目标是阻止下载速度大于指定值,则连接数也应该受到限制。例如,每个 IP 地址一个连接(如果使用上面指定的共享内存区域):

location /download/ {
    limit_conn addr 1;
    limit_rate 50k;
}

要仅在客户端下载一定数量的数据后施加限制,请使用该 limit_rate_after 指令。允许客户端快速下载一定数量的数据(例如,文件头 - 电影索引)并限制下载其余数据的速率(使用户观看电影而不是下载)可能是合理的。

limit_rate_after 500k;
limit_rate 20k;

以下示例显示了用于限制连接数和带宽的组合配置。允许的最大连接数设置为每个客户端地址 5 个连接,这适用于大多数常见情况,因为现代浏览器通常一次最多打开 3 个连接。同时,提供下载的位置只允许一个连接:

http {
    limit_conn_zone $binary_remote_address zone=addr:10m

    server {
        root /www/data;
        limit_conn addr 5;

        location / {
        }

        location /download/ {
            limit_conn addr 1;
            limit_rate_after 1m;
            limit_rate 50k;
        }
    }
}

内容翻译自 nginx 请求限制部分文档,稍微调整了一点语义。

相关推荐

Nginx 如何对单个 url 的访问频率进行限制

Nginx 如何对单个 url 的访问频率进行限制

近期有不法人员针对公司的登录地址进行非法暴力破解,所以本人加上了登录页面的单个 ip 的频率限制写法如下! http 模块中加入: http { #定义一个名为allips的limit_req_zone用来存储session,大小是10M内存, #1M能存储16000个状态,rete的值必须为整数, #限制两秒钟一个请求,设置成30r/m ...... limit_req_zone $binar ...

Nginx 对 IP 和 URL 进行访问频率的限制

Nginx 对 IP 和 URL 进行访问频率的限制

HttpLimitReqModul 为 nginx 官方自带的限制单位时间内请求次数的功能模块,通过 limit_req_zone 和 limit_req 命令配合使用来达到限制。一旦对应的累计连接超过指定数量,就会返回 503 错误。可以利用该规则对 IP 和 URL 进行访问频率的限制。 1. 限制规则 limit_req_zone $binary_remote_addr zone=ip_second:10m rate=10 ...

使用 Nginx 限流模块 limit_req_zone 来限制单位时间内的请求数目/速度/连接数

使用 Nginx 限流模块 limit_req_zone 来限制单位时间内的请求数目/速度/连接数

根据 nginx 官网提供的说法,有两种算法,一种是漏桶算法,一种是令牌桶算法。limit_req_zone 用来限制单位时间内的请求数目,以及速度限制;limit_req_conn 用来限制同一时间连接数,即并发限制。 1. 限流算法介绍 1.1 令牌桶算法 令牌桶: 1.2 漏桶算法 漏桶算法: 相比漏桶算法,令牌桶算法不同之处在于它不但有一只“桶”,还 ...

解析 Nginx limit_req 模块的 burst 参数,实现限制 IP 地址 URL 访问频率

解析 Nginx limit_req 模块的 burst 参数,实现限制 IP 地址 URL 访问频率

漏斗算法(Leaky Bucket),该算法有两种处理方式 Traffic Shaping 和 Traffic Policing 在桶满水之后,常见的两种处理方式为: 将水看作网络通信中数据包的抽象,则 方式1 起到的效果称为 Traffic Shaping ,方式2 起到的效果称为 Traffic Policing。由此可见,Traffic Shaping的核心理念是"等待",Traffic Policing 的核 ...

微信扫一扫,分享到朋友圈

Nginx 资源请求限制:链接数/请求速率/宽带