ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ngx-lua实现高级限流方式一

2022-05-07 21:33:56  阅读:182  来源: 互联网

标签:index req lua 限流 limit ngx fastcgi


基于POST请求体中的某个参数限流

背景

电商平台有活动,活动涉及优惠券的抢券,优惠券系统对大并发支持略差,为了保护整体系统平稳,因此在入口Nginx层对抢券接口做了一层限流。

完整实现如下:

lua_shared_dict my_limit_req_store 100m;
server {
    listen 80;
    server_name test.abc.com;

    # 抢券接口
    location = /api/v1/test {
        lua_need_request_body on;

        access_by_lua_block {
            local cjson = require("cjson")

            -- 获取POST请求体
            if ngx.var.request_method == "POST" then
                ngx.req.read_body()

                local data = ngx.req.get_body_data()
                -- 获取限流字段 appName, 获取不到则跳出lua
                if data then
                    params = cjson.decode(data)
                    if params["appName"] then
                        limit_key = params["appName"]
                    else
                        ngx.log(ngx.ERR, "未获取到appName,不做限流")
                        -- 退出access_by_lua阶段,继续执行其他阶段。
                        ngx.exit(0)
                    end
                else
                    ngx.log(ngx.ERR, "获取请求体失败,跳过限流配置")
                    ngx.exit(0)
                end
            else
                ngx.log(ngx.ERR, "不对非POST请求进行处理")
                ngx.exit(0)
            end

            -- 限流逻辑
            local limit_req = require "resty.limit.req"
            local lim, err = limit_req.new("my_limit_req_store", 200, 100)
            if not lim then
                    ngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err)
                    return ngx.exit(500)
            end

            local delay, err = lim:incoming(limit_key, true)
            if not delay then
                if err == "rejected" then
                    return ngx.exit(503)
                end
                ngx.log(ngx.ERR, "failed to limit req: ", err)
                return ngx.exit(500)
            end

            if delay >= 0.001 then
                local excess = err
                ngx.sleep(delay)
            end
        }

        try_files $uri $uri/ /index.php?$query_string;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location  ~ \.php$ {
        # 设置项目根目录
        set $PROJECT_NAME "/data/www/test.abc.com/public";
        # 设置upstream_name
        set $fastcgi_name test;

        index index.php index.html index.htm;
        include  fastcgi_params;
        fastcgi_pass   $fastcgi_name;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $PROJECT_NAME$fastcgi_script_name;     # 指定项目根目录
    }
}

核心解读

  1. 获取请求体

    1. POST请求
    2. JSON格式
    3. 获取不到不能影响其他阶段继续执行
  2. 解析请求体获取目标参数

    1. cjson.decode()
    2. 操作map获取目标数据(限流的指标)
    3. 获取不到不能影响其他阶段继续执行
  3. 确定限流方式

    1. 限请求速率
    2. 限连接数

标签:index,req,lua,限流,limit,ngx,fastcgi
来源: https://www.cnblogs.com/chaizhenhua/p/16244176.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有