前言
前段时间,所负责的项目疑似被爬虫爬取了;于是考虑从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/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;
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
小结
简单来说,如果想要比较准确的限制爬虫等非法请求,尽量两个模块结合使用
网友评论