Nginx请求限制

Nginx请求限制

Nginx 中,我们经常会遇到这种情况,服务器流量异常,负载过大等等。对于大流量恶意的攻击访问,会带来带宽的浪费,服务器压力,影响业务,往往考虑对同一个 ip 的连接数,并发数进行限制。http_limit_conn_module 模块来实现。

该模块可以根据定义的键来限制每个键值的连接数,如同一个 IP 来源的连接数。并不是所有的连接都会被该模块计数,只有那些正在被处理的请求(这些请求的头信息已被完全读入)所在的连接才会被计数。

http_limit_req_module 模块来实现,该模块可以通过定义的 键值来限制请求处理的频率。特别的,可以限制来自单个 IP 地址的请求处理频率。 限制的方法如同漏斗,每秒固定处理请求数,推迟过多请求。

http_limit_conn_module

语法

limit_conn_zone $variable zone=name:size;

使用环境

http

说明

该指令描述会话状态存储区域。键的状态中保存了当前连接数,键的值可以是特定变量的任何非空值(空值将不会被考虑)。$variable 定义键,zone=name 定义区域名称,后面的 limit_conn 指令会用到的。size 定义各个键共享内存空间大小。如:

limit_conn_zone $binary_remote_addr zone=addr:10m;

客户端的 IP 地址作为键。注意,这里使用的是 $binary_remote_addr 变量,而不是 $remote_addr 变量。

$remote_addr 变量的长度为 7 字节到 15 字节,而存储状态在 32 位平台中占用 32 字节或 64 字节,在 64 位平台中占用 64 字节。

$binary_remote_addr 变量的长度是固定的 4 字节,存储状态在 32 位平台中占用 32 字节或 64 字节,在 64 位平台中占用 64 字节。

1M 共享空间可以保存 3.2 万个 32 位的状态,1.6 万个 64 位的状态。如果共享内存空间被耗尽,服务器将会对后续所有的请求返回 503 (Service Temporarily Unavailable) 错误。

limit_zone 指令和 limit_conn_zone 指令同等意思,已经被弃用,就不再做说明了。

limit_req_zone

语法

limit_req_zone $variable zone=name:size rate=rate;

使用环境

http

说明

设置一块共享内存限制域用来保存键值的状态参数。 特别是保存了当前超出请求的数量。 键的值就是指定的变量(空值不会被计算)。如:

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

区域名称为 one,大小为 10m,平均处理的请求频率不能超过每秒一次。键值是客户端 IP。

使用 $binary_remote_addr 变量, 可以将每条状态记录的大小减少到 64 个字节,这样 1M 的内存可以保存大约1 万 6 千个 64 字节的记录。

如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回 503 (Service Temporarily Unavailable)错误。

速度可以设置为每秒处理请求数和每分钟处理请求数,其值必须是整数,所以如果你需要指定每秒处理少于 1 个的请求,2 秒处理一个请求,可以使用 “30r/m”。

Nginx请求限制

我们首先使用 vim 打开 nginx 的默认配置路径,具体命令如下:

vim /etc/nginx/conf.d/default.conf

如下图所示:

24_nginx连接限制.png

我们执行如上命令,打开配置文件,接着,我们修改 server 下面的根路径的 location 配置,具体配置如下:

limit_conn_zone $binary_remote_addr zone=conn_zone:1m; limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s; server { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } }

配置完毕后,如下图所示:

25_nginx连接限制.png

现在,我们重新加载配置文件,具体命令如下:

nginx -s reload

现在,我们使用 ab 命令,进行压力测试,具体命令如下:

ab -n 40 -c 20 http://127.0.0.1/

执行完毕后,如下图所示:

26_nginx连接限制.png

我们看到,完成了 40 个请求,现在,我们修改配置如下:

limit_conn_zone $binary_remote_addr zone=conn_zone:1m;limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;server { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; #limit_conn conn_zone 1; #limit_req zone=req_zone burst=3 nodelay; #limit_req zone=req_zone burst=3; limit_req zone=req_zone; index index.html index.htm; }}

请求限制打开,重新加载 Nginx 配置,1s 同一个客户端只允许连接一次,我们再次进行测试,具体命令如下:

ab -n 40 -c 20 http://127.0.0.1/

执行完毕后,如下图所示:

27_nginx连接限制.png

我们看到,失败了 39 个,只成功了一个,即,我们的限制生效了。

Nginx请求限制总结

在 Nginx 中,我们经常会遇到这种情况,服务器流量异常,负载过大等等。对于大流量恶意的攻击访问,会带来带宽的浪费,服务器压力,影响业务,往往考虑对同一个 ip 的连接数,并发数进行限制。