nginx limit_req_zone用法详解

nginx可以使用ngx_http_limit_req_module模块的limit_req_zone指令进行限流访问,防止用户恶意攻击刷爆服务器。
ngx_http_limit_req_module模块是nginx默认安装的,所以直接配置即可。

首先,在nginx.conf文件中的http模块下配置:

limit_req_zone $binary_remote_addr zone=commonper:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=50per:10m rate=50r/s;

说明:
区域名称为commonper 和 50per(自定义),占用空间大小为10m,平均处理的请求频率不能超过每秒十次,50per的每秒50次。
我这里配置了两种不同规格的配置,用于子模块配置时可自由指定。

$binary_remote_addr$remote_addr(客户端IP)的二进制格式,固定占用4个字节(可能是C语言的long类型长度)。

第二,在http模块的子模块server下面配置

location ~^(.+\.php)(.*)$ {
   	limit_req zone=commonper burst=50;
	...
}

这里是对项目中所有请求限制。
高速的可选择 zone=50per

注意zone=commonper和前面的定义对应。

burst是缓冲队列的长度。

nodelay字面的意思是不延迟,具体说是对用户发起的请求不做延迟处理,而是立即处理。比如我上面定义的rate=10r/s,即每秒钟只处理10个请求。
如果同一时刻有11个请求过来,若设置了nodelay,则会立刻处理这两个请求。若没设置nodelay,则会严格执行rate=10r/s的配置,即只处理十个请求,然后下一秒钟再处理剩下一个请求。

真正对限流起作用的配置就是rate=10r/s和burst=50这两个配置。

下面我们来分析一下具体案例。

某一时刻有两个请求同时到达nginx,其中一个被处理,另一个放到了缓冲队列里。虽然配置了nodelay导致第二个请求也被瞬间处理了,但还是占用了缓冲队列的一个长度,如果下一秒没有请求过来,这个占用burst一个长度的空间就会被释放,否则就只能继续占用着burst的空间,直到burst空间占用超过5之后,再来请求就会直接被nginx拒绝,返回503错误码。

可见,如果第二秒又来了两个请求,其中一个请求又占用了一个burst空间,第三秒、第四秒直到第五秒,每秒都有两个请求过来,虽然两个请求都被处理了(因为配置了nodelay),但其中一个请求仍然占用了一个burst长度,五秒后整个burst长度=5都被占用了。第六秒再过来两个请求,其中一个请求就被拒绝了。

原文参考:https://blog.csdn.net/keketrtr/article/details/75315330

你可能感兴趣的:(Nginx)