本篇文章来讲下Nginx限流的一些知识,因为在一些业务场景中可能会使用得到,比如:抢购的场景(如果短时间内大量的请求涌向服务器可能会导致服务器崩溃),下载限速等应用场景。
限流:主要当访问量达到一个限量的时候可以选择以服务器为主要,而选择对用户访问请求的量做限制,对于超出限制的用户请求会采取丢弃或者延迟处理等方式处理,来保证更多的用户来访问处理。
一 、 ngx_http_limit_req_module限制请求频率
语法:limit_req_zone $variable zone=name:size rate=rate;
示例:
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s
...
location /search/ {
limit_req zone=one burst = 5
}
}
其中每个字段的含义如下:
zone=one:10m 表示设置了名为"one",大小为10M字节,也就是分配了一块内存区域大小为10M,来负责保存请求的一些状态信息,它特别保存了当前超出请求的数量。
rate=10r/s 的意思是允许1秒钟不超过10个请求,速度可以设置为每秒处理请求数和每分钟(10r/m)处理请求数,其值必须是整数,也可以理解为100毫秒处理一个请求,如果在100毫秒内有超过1个的请求就会被拒绝或者缓存起来(取决于是否配置了burst)。
$binary_remote_addr
: 这是个二进制的信息记录($remote_addr 非二进制的,nginx本身存在的,保存客户端的ip地址的变量),可以将每条状态记录的大小减少到64个字节,这样1M的内存可以保存大约1万6千个64个字节的记录。如果限制域耗尽了,对于后续的所有请求,服务器都会返回503错误(服务器当前不可用);
limit_req_zone=one 这里的意思是引用了上面那个限流规则:one ;
burst = 5 允许超过频率限制的请求数不多余5个;超过5个的请求将会返回503错误;
如果不希望超过的请求被延迟处理,可以用nodelay参数,例如: limit_req zone=one burst = 5 nodelay,举个例子:第一秒有15个请求(rate=10/r),那么多余的5个请求会在这一秒内同时处理,否则就会放到下一秒去处理。
那么上面这个示例配置的意思就是:对search路径的访问进行了ip限制(注意这里是对所有的ip地址),对于不同的ip每秒的请求数限制为10,多余的请求将被延续处理,如果没有加burst这个参数的话,多余的请求就会被拒绝。
下面我们来测试下:
使用的工具jmeter,由于这个工具是java写的,所以小伙伴们还得安装下jdk才能使用。下面来针对不同的情况分别做测试:
1.1 设置rate=10r/s,burst=5
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s
...
location /search/ {
limit_req zone=one burst = 5
}
}
先启动jmeter,在TestPlan下分别添加线程组,HTTP请求,查看结果数,如下图所示:
jmeter.png
其中线程组中配置线程数10个(表示并发数),Ramp-Up时间表示执行完这些线程的时间,这里我们设置为0.01,另外需要在http请求那里设置请求的接口,如下图所示:
jmeter.png
一般设置红色标出的地方就行了,下面点击运行查看下结果:
jmeter.png
下面再来看下nginx的access.log文件的访问日志记录:
jmeter.png
可以看到这10个请求几乎是同时到达的,在nginx处理第一个请求的时候其他的请求就会被缓存起来(burst=5),超过5个的请求将会被返回503错误。
现在我们把nginx配置中的burst这个去掉看看运行结果:
jmeter.png
发现只有一个请求是正确的,其他的都返回503错误,因为这些请求几乎是同时到达的,nginx在处理请求的同时,其他的请求就会被拒绝。
下面再看下加上nodelay参数的运行效果:
jmeter.png
和之前不加nodelay的运行结果相比,被正确执行的这几个请求几乎是同时执行的,而没有加nodelay的多余的请求就放到了下一秒去执行了。
网友评论