限速限流
为什么要限速
限制某个用户在一定时间内能够产生的Http请求或者限制某个用户的下载速度.防止个别用户对资源消耗过多,导致其它用户受影响. 启用限速后,如果超过指定的阈值,则提示503过载保护
限速相关模块
下载限速:限制用户下载资源的速度
ngx_http_core_module
请求限制:限制用户单位时间内所产生的Http请求数
ngx_http_limit_req_module
连接限制:限制同一时间的连接数,即并发数限制
ngx_http_limit_conn_module
请求频率限速原理
先将请求放置缓存中,然后按指定速度持续处理.当请求速度超过了处理速度会导致缓存被占满,如果 还有没有放入缓存的请求,则会被丢弃.工作原理类似漏斗
限制下载速度范例(前100MB不限速,超过100MB之后限速100K)
vim /apps/nginx/conf/conf.d/mirrors.meng.conf
server{
listen 80;
server_name mirrors.meng.org;
autoindex on; #文件自动索引功能开启
autoindex_exact_size off #关闭精确大小,容易看文件大小
limit_rate 100k; #限速100k 在另一机器curl -O 可看下载速度 -k忽略证书
limit_rate_after 100m; #下载达到100MB数据后开始限速
charset utf8; #默认字符集
root /data/nginx/html/mirrors/;
}
限制请求数(限制同一个IP的同时发起的最大请求数)
官方文档:ttp://nginx.org/en/docs/http/ngx_http_limit_req_module.html
Syntax: limit_req_zone key zone=name:size rate=rate [sync];
Default: —
Context: http
Syntax: limit_req zone=name [burst=number] [nodelay | delay=number];
Default: —
Context: http, server, location
Syntax: limit_req_status code;
Default:
limit_req_status 503;
Context: http, server, location
示例:
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; #每秒10个请求
...
server {
...
location /search/ {
limit_req zone=one burst=5;
limit_req_status 500; # 默认503,可以指定其他状态码
}
参数说明:
limit_req_zone定义在http块中,$binary_remote_addr表示以客户端IP地址的二进制形式为限流依据的key
Zone定义IP状态及URL访问频率的共享内存区域.zone=keyword标识区域的名字,以及冒号后面跟区域大小.8000个IP地址的状态信息约1MB,例子区域可以存储80000个IP地址.
Rate定义最大请求速率.示例中速率不能超过每秒10个请求.超过此速率的请求放入burst队列做延迟处理
burst表示队列大小,当此队列满后,会中断请求报错
nodelay表示超过请求速率并且缓存区满后不延迟处理,立即返回503错误
#可以有几个limit_req指令.例如,以下配置将限制来自单个IP地址的请求的处理速率,同时限制虚拟服务器的请求处理速率
范例:基于来源IP对下载速率限制,限制每秒处理1次请求,缓存区请求突发队列为10个
http标签段定义请求限制, rate限制速率,限制一秒钟最多一个IP请求
注意 : $remote_addr和$binary_remote_addr的不同
vim /apps/nginx/conf/conf.d/www.meng.org.conf
limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
#限制ip,同一个用户限制1s1个请求
server {
listen 80 ;
server_name www.meng.org;
root /data/nginx/html/pc/;
limit_req zone=req_one burst=10 nodelay; 允许10个队列请求,再多就拒绝了。
}
nginx -s reload
查看日志: tail -f /apps/nginx/logs/error.log
访问www.meng.org 超过10个后报状态码503 限制请求连接,超过之后就丢弃了。
限制并发连接数(限制同一个IP同时发起的最大并发连接数)
格式:
Syntax: limit_conn_zone key zone=name:size;
Default: —
Context: http
Syntax: limit_conn zone number;
Default: —
Context: http, server, location
范例:设置共享内存区域和给定键值的最大允许个连接数.超过此限制时服务器将返回503错误
vim /apps/nginx/conf/conf.d/www.meng.org.conf
limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
server {
listen 80 ;
server_name www.meng.org;
root /data/nginx/html/pc/;
limit_conn conn_zone 2; 限制两个并发
}
nginx -s reload
测试:ab -c 2 -n 10 http://www.meng.org/ 并发两个总共10个
查看日志:tail /apps/nginxlogs/error.log 正常
测试:ab -c 3 -n 10 http://www.meng.org/ 并发两个总共10个
查看日志:出现错误 报状态码503,限制连接请求,超过并发量
综合实战
实现百度云盘非会员限度限流功能:
当下载超过100M则限制下载速度为500k
限制web服务器请求数处理为1秒一个,触发值为5,限制用户仅可同时下载一个文件.
如果同时下载超过2个资源,则返回提示 "请联系管理员进行会员充值" 并跳转到其他页面
范例
vim /etc/nginx/conf.d/mirrors.meng.conf
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
server {
listen 80;
server_name mirrors.meng.org;
root /data/mirrors/;
charset utf8;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
limit_req zone=req_zone burst=5 nodelay;
limit_conn conn_zone 2;
limit_rate_after 100m;
limit_rate 500k;
error_page 503 @error_page;
location @error_page {
default_type text/html;
return 200 '温馨提示:请联系管理员进行会员充值!';
#return 200'Tips: Please contact the administrator for recharge!';
#return https://pan.baidu.com/buy/center?tag=8&from=loginpage#/svip;
}
}
nginx -s reload
在/data/nginx/pc/目录下写两个答文件
dd if=/dev/zero of=f1.img bs=1M count=200
dd if=/dev/zero of=f2.img bs=1M count=200
在另一主机开启两个窗口建立两次连接,进行资源下载
wget http://www.meng.org/f1.img
wget http://www.meng.org/f1.img
在开启第三次下载资源时,下载失败,出现温馨提示
curl http://www.meng.org/f1.img -I
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.22.0
Date: Wed, 14 Sep 2022 10:37:19 GMT
Content-Type: text / html
Content-Length: 145
Connection: keep-alive
Location:温馨提示:请联系管理员进行会员充值!