限流原则:每个IP每秒只能访问n次
http {
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
·······
location / {
limit_req zone=mylimit burst=5 nodelay;
limit_req _log_level error;
limit_req_status 503;
·······
}
}
step1:定义请求限制空间
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
1. $binary_remote_addr,表明是以remote_addr为限制目标,加上binary是为了压缩内存占用空间
remote_add记录的是ip地址信息,如:“192.168.1.222”会占用7到15个字节,
而如果用binary_remote_addr只会占用4个字节。
就相当于不同的表示方式,一个全程一个缩写的表示。
2. zone=name:size,分配一个以name为名的并且大小为size的内存空间,用来存储访问的频次信息
1M能存储16000 IP地址的访问信息,10M可以存储16W IP地址访问信息。如果区域存储耗尽,则删除最近最少使用的状态。如果即使在此之后无法创建新状态,请求也会以错误终止。--If storage is exhausted when NGINX needs to add a new entry, it removes the oldest entry. If the space freed is still not enough to accommodate the new record, NGINX returns status code
503
(Service
Temporarily
Unavailable)
.
3. rate=nr/s, 如rate=1r/s表示同一个IP每秒只允许一个请求通过。
Nginx 实际上以毫秒为粒度来跟踪请求信息,因此 10r/s 实际上是限制:每100毫秒处理一个请求。这意味着,自上一个请求处理完后,若后续100毫秒内又有请求到达,将拒绝处理该请求。
step2:定义请求限制
limit_req zone=mylimit burst=5 nodelay;
1.zone=mylimit,使用step1定义的空间
2.brust=x,表示设置一个大小为x的缓冲区,超过频次限制的请求先放入这个缓冲区。
若同时有x+1个请求到达,Nginx 会处理第一个请求,剩余x个请求将放入队列,然后每隔100ms(10r/s)从队列中获取一个请求进行处理。若请求数大于21,将拒绝处理多余的请求,直接返回503.
3.nodelay,不延迟处理。
nodelay 针对的是 burst 参数,burst=x nodelay 表示这x个请求立马处理,不能延迟,相当于特事特办。即使这x个突发请求立马处理结束,后续来了请求也不会立马处理。burst=x 相当于缓存队列中占了x个坑,即使请求被处理了,这x个位置这只能按 100ms(10r/s)一个来释放。
3.1 delay,前delay个不延迟处理,burst-delay的请求延迟处理,超过burst的503.
rate=5r/s,brust=12,delay=8
The first 8 requests (the value of
delay
) are proxied by NGINX Plus without delay. The next 4 requests (burst
-
delay
) are delayed so that the defined rate of 5 r/s is not exceeded. The next 3 requests are rejected because the total burst size has been exceeded. Subsequent requests are delayed
3.2 nodelay/delay都不填,就按照rate,一个个处理,超过brust直接返回503.
实际应用:
如果作为代理服务器,我们需要限制每个用户的请求速度和链接数量,但是,由于一个页面有多个子资源,如果毫无选择的都进行限制,那就会出现很多不必要的麻烦,如:一个页面有40个子资源,那么如果想让一个页面完整的显示,就需要将请求速度和连接数都调整到40,以此达到不阻塞用户正常请求,而这个限制,对服务器性能影响很大,几百用户就能把一台nginx的处理性能拉下来。
所以我们需要制定哪些请求是需要进行限制的,如html页面;哪些是不需要限制的,如css、js、图片等,这样就需要通过配置对应的location进一步细化。
我们不对css、js、gif、png,jpg等进行连接限制,而对除此之外的链接进行限制。
location ~ .*\.(gif|png|css|js|icon)$ {
proxy_set_header Host $http_host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* .*\.(jpeg|jpg|JPG)$ {
proxy_set_header Host $http_host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#p_w_picpath_filter resize 480 -;
#p_w_picpath_filter_jpeg_quality 50;
#p_w_picpath_filter_sharpen 10;
#p_w_picpath_filter_buffer 4M;
}
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#limit
limit_conn addr 3;
limit_req zone=one burst=5;
}
资料来源:
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
https://www.jianshu.com/p/6386925be627
https://blog.csdn.net/myle69/article/details/83512617
https://www.cnblogs.com/pengyunjing/p/10662612.html