当前位置: 首页 > 工具软件 > lua-limit > 使用案例 >

nginx+lua实现限流降级(使用lua的lua-resty-limit-traffic)

严永丰
2023-12-01

前言

虽然nginx中自带了限流的模块,只能直接限定超出的数量,但对于允许范围内的流量如何进行限流是个问题。nginx的限流方式!

 limit_conn perserver 100;
 limit_conn perip 15;
 limit_rate 512k;

但是比如这100的允许的值,0-30个请求去mysql读数据,31-70去redis读数据,71-100去文件直接读数据,nginx不好做这个事情,所以引入lua的lua-resty-limit-traffic来设计。

local limit_req = require "resty.limit.req"
-- 这里设置rate=50个请求/每秒,漏桶桶容量设置为1000个请求
-- 因为模块中控制粒度为毫秒级别,所以可以做到毫秒级别的平滑处理
-- my_limit_req_store是共享内存,请在http中设置一下  lua_shared_dict my_limit_req_store 100m;
local lim, err = limit_req.new("my_limit_req_store", 50, 1000)
if not lim then
    ngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err)
    return ngx.exit(501)
end

local key = ngx.var.binary_remote_addr
local delay, err = lim:incoming(key, true)


ngx.say("计算出来的延迟时间是:")
ngx.say(delay)

--if ( delay <0 or delay==nil ) then
    --return ngx.exit(502)
--end


-- 1000以外的就溢出
if not delay then
    if err == "rejected" then
        return ngx.say("1000以外的就溢出")
        -- return ngx.exit(502)
    end
    ngx.log(ngx.ERR, "failed to limit req: ", err)
    return ngx.exit(502)
end

-- 50-100的等待从微服务+mysql获取实时数据;(100-50)/50 =1
if ( delay >0 and delay <=1 ) then
    ngx.say("第50-第100个 等待0-1秒后 从mysql获取数据")
    ngx.sleep(delay)

-- 100-400的直接从redis获取实时性略差的数据;(400-50)/50 =7
elseif ( delay >1 and delay <=7 ) then
    local resp, err = redis_instance:get("redis_goods_list_advert")
    ngx.say("第100-第400个 降级为从redis获取数据")
    ngx.say(resp)
    return

-- 400-1000的从静态文件获取实时性非常低的数据(1000-50)/50 =19
elseif ( delay >7) then

    ngx.say("第400-第1000个 降级为从静态文件(死页面)获取数据")
    ngx.header.content_type="application/x-javascript;charset=utf-8"
    local file = "/etc/nginx/html/goods_list_advert.json"
    local f = io.open(file, "rb")
    local content = f:read("*all")
    f:close()
    ngx.print(content)
    return
end


ngx.say("进入查询微服务+mysql(最实时的数据,进入这里就是没降级)")

 类似资料: