OpenResty 限制下载速度,openresty下载速度
OpenResty 限制下载速度,openresty下载速度
http://blog.donatas.net/blog/2017/07/25/limit-bandwidth-openresty/
Nginx 有两个非常棒的模块用来限制响应(responses)的速度
- limit_rate 对一个客户端限制速率 bytes/每秒
- limit_rate_after
一般情况没问题,但是视频流传输就不好用了
location / {
limit_rate_after 500k;
limit_rate 50k;
...
}
上面的配置意味着,你可以缓冲500k然后开始限速(me:有点类似视频开头不限速,后面才开始限速), 如果你使用 browser/player/whatever
来播放,就会发现每次缓冲都会使用新建一个请求,相当于限速的作用被削弱了。
如果我想把这些限制只用于视频流,而不是简单的wget这种模式呢(视频流是chunk的)? 我的意思是 - 以反向指数方式,相同URI限制下一个请求,如反向TCP拥塞行为。(me:同一个客户端的并发请求能全局限速, 可以感知并发)
尽可能使用简单的方式实现,但不是越简单越好
为每个 uri 创建SHA256
的hash,并且设置5分钟的有效期,这期间对每个请求进行计数。计数器是用来指数级的加大限速
26214400
6553600
1638400
409600
102400
25600
6400
...
router.conf:
location / {
set $limit_rate '';
set $limit_rate_after '';
access_by_lua_file conf/router.lua;
proxy_buffering on;
...
}
router.lua:
ocal request_count = function ()
local resty_sha256 = require "resty.sha256"
local str = require "resty.string"
local sha256 = resty_sha256:new()
sha256:update(ngx.var.http_host .. ngx.var.request)
local digest = sha256:final()
local key = "request:" .. str.to_hex(digest)
local ok, err = redis:connect("127.0.0.1")
if not ok then
return nil, err
end
local ok, err = redis:auth("something")
if not ok then
return nil, err
end
local data, _ = redis:get(key)
redis:incr(key)
redis:expire(key, 300)
return data
end
local bw_limit = 104857600
if request_count() ~= ngx.null then
bw_limit = math.max(10240, math.floor(bw_limit / 2 ^ request_count()))
end
ngx.var.limit_rate = bw_limit
ngx.var.limit_rate_after = 8388608
这样在一段时间里,就无法通过并发方式来突破限速了。
评论暂时关闭