Rootop 服务器运维与web架构

nginx模块 – ngx_http_limit_req_module测试

此模块用于限制单个ip请求速率,每秒多少次。

模块文档:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

rate参数的几个写法含义:

limit_req_zone $binary_remote_addr zone=limit_login:10m rate=10r/m;
代表单ip每6秒1个请求(60/10=6)
limit_req_zone $binary_remote_addr zone=limit_login:10m rate=20r/m;
代表单ip每3秒1个请求(60/20=3)
limit_req_zone $binary_remote_addr zone=limit_login:10m rate=30r/m;
代表单ip每2秒1个请求(60/30=2)(官方文档叫half-request per second 1秒半个请求)
limit_req_zone $binary_remote_addr zone=limit_login:10m rate=1r/s;
代表单ip每秒1个请求
limit_req_zone $binary_remote_addr zone=limit_login:10m rate=2r/s;
代表单ip每秒2个请求

开始以为rate=30r/m 这参数意味着一分钟内30个请求,结果测试发现不对,仔细看官方文档是一秒—半个请求

当前配置为:2秒一个,突发burst为5个,意味着同一个ip可以再发起5个排队请求。

limit_req_zone $binary_remote_addr zone=limit_login:10m rate=30r/m; 
# 注意上面这个配置是在server{}之上
server
{
    略过部分配置...
	# 这里实现针对某个url进行限制
	location = /login.php
	{
		limit_req zone=limit_login burst=5;
		limit_req_log_level info;
		limit_req_status 555;

		try_files $uri =404;
		fastcgi_pass  unix:/tmp/php.sock;
		fastcgi_index index.php;
		include fastcgi.conf;
		include pathinfo.conf;
	}
}

第一次访问login.php,会马上显示页面内容。(此时处在突发burst值以下)
第二次连续按2下刷新,会加载转圈2秒钟才显示,因为第一个请求处理后需要2秒后(速率限制)再处理第二个,(此时处在突发值以下,进入队列。)
第三次连续按3下刷新,大约4秒后显示。因为第一个请求2秒+第二个请求2秒。(此时处在突发值以下,进入队列。)
第四个连续按4下刷新,大约6秒后显示,2+2+2=6秒。(此时处在突发值以下,进入队列。)
第五次连续按5下刷新,会在8秒后显示,2+2+2+2=8秒。(此时等于突发值。)
第六次连续按6下或7下刷新(7下是因为按的第一次可能已经处理完成,手动按的刷新浏览器的速度赶不上处理速度快),直接返回555状态码,因为超过突发值了。

如果一直在刷新,那么就会一直返回555状态码,只有在返回555状态,并且没有在30r/m时间内,也就是2秒内没有新请求进来(同一个ip),大约在10秒(2秒一个请求*5个最大突发)后突发请求处理完后就可以再次访问了。

这种限流方法只适用于没有cdn加速的情况下,否则会取到cdn的ip,并不能取到真实客户端ip,此模块也不能用$x_forward_for字段获取真实ip。会报语法错误。
如果有能力改模块源码的话应该可以实现。

原创文章,转载请注明。本文链接地址: https://www.rootop.org/pages/4701.html

作者:Venus

服务器运维与性能优化

评论已关闭。