此模块用于限制单个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