Open bingoohuang opened 3 years ago
mkdir conf.d
创建 conf.d/nginx_limit.conf 文件,内容如下
lua_shared_dict my_limit_req_store 100m;
server {
listen 8700;
default_type text/html;
location / {
return 200 OK;
}
location /limit {
access_by_lua_block {
local limit_req = require "resty.limit.req"
-- 限制每秒 200 个请求 (rate),以及 100 的等待队列 (burst), 超过每次 300,直接拒绝
local rate = tonumber(ngx.var.arg_rate or 200)
local burst = tonumber(ngx.var.arg_burst or 100)
local lim, err = limit_req.new("my_limit_req_store", rate, burst)
if not lim then
ngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err)
return ngx.exit(500)
end
-- 以远端IP为限制 key
local delay, excess = lim:incoming(ngx.var.binary_remote_addr, true)
if excess == "rejected" then
ngx.log(ngx.ERR, "rejected")
-- ngx.say, ngx.print 发送消息包,必然要先发送消息头,所以需要提前设置 response status (默认为200)
ngx.status = 503
ngx.say("XX delay:", delay, ", rate: ", rate, ", burst: ", burst)
return ngx.exit(503)
end
ngx.say("OK delay: ", delay, ", rate: ", rate, ", burst: ", burst, ", excess: ", excess)
return ngx.exit(200)
}
}
}
docker pull openresty/openresty:1.19.9.1-2-buster-fat
docker run -d -p 8700:8700 -v $(pwd)/conf.d:/etc/nginx/conf.d openresty/openresty:1.19.9.1-2-buster-fat
docker logs stoic_elbakyan
查看日志blow ":8700/limit?rate=200&burst=10" -d 1m
blow ":8700/limit?rate=200&burst=100" -d 1m
blow ":8700/limit?rate=200&burst=100" -d 1m -c 2 --qps 100
blow ":8700/limit?rate=200&burst=100" -d 1m -c 10 --qps 20
QPS设在200时,未触发限流(5xx)
限流算法解读
漏桶算法
漏桶(Leaky Bucket)算法,水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当流入速度过大时,会直接溢出(访问频率超过接口响应速率),然后就拒绝请求,而当入小于出的情况下,漏桶不起任何作用。可以看出漏桶算法能强行限制数据的传输速率。示意图如下:
注意:在实际应用中,漏桶算法强制限定流量速率后,多出的(溢出的 excess)流量可以被利用起来,并非完全丢弃,我们可以把它收集到一个队列(burst) 里面,做流量队列,尽量做到合理利用所有资源。
漏桶算法:水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出(拒绝服务),可以看出漏桶算法能强行限制数据的传输速率
用白话具体说明:假设漏斗总支持并发100个最大请求,如果超过100个请求,那么会提示系统繁忙,请稍后再试,数据输出那可以设置1个线程池,处理线程数5个,每秒处理20个请求。
openresty/lua-resty-limit-traffic源码解读
参考文章