基于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. 限连接数

ngx-lua实现高级限流方式一的更多相关文章

  1. Lua学习高级篇

    Lua学习高级篇 之前已经说了很多,我目前的观点还是那样,在嵌入式脚本中,Lua是最优秀.最高效的,如果您有不同的观点,欢迎指正并讨论,切勿吐槽.这个系列完全来自于<Programming in ...

  2. ngx.lua中遇到的小问题2

    用lua+drizzle在数据库中插入数据失败(不能访问数据库) 后面发现原来是nginx配置文件中的drizzle模块部分最后多了一行  content_by_lua 'ngx.say(" ...

  3. ngx.lua中遇到的小问题

    作者: 胡 志伟 分类: ngx_lua, 开发代码 发布时间: 2013-09-26 08:40 ė 6评论关闭 在使用ngx.redirect 到一个新的地址时,错误日志提示: lua entry ...

  4. java并发系列 - 第29天:高并发中常见的限流方式

    这是java高并发系列第29篇. 环境:jdk1.8. 本文内容 介绍常见的限流算法 通过控制最大并发数来进行限流 通过漏桶算法来进行限流 通过令牌桶算法来进行限流 限流工具类RateLimiter ...

  5. ngx lua获取时间戳的几种方式

    原创自由de单车 最后发布于2017-02-14 14:58:43 阅读数 18218 收藏 在ngx_lua里,获取时间相关信息的方式大概有4种(见下面代码): print(string.forma ...

  6. Spring Cloud Alibaba | Sentinel: 服务限流高级篇

    目录 Spring Cloud Alibaba | Sentinel: 服务限流高级篇 1. 熔断降级 1.1 降级策略 2. 热点参数限流 2.1 项目依赖 2.2 热点参数规则 3. 系统自适应限 ...

  7. 从SpringBoot构建十万博文聊聊限流特技

    前言 在开发十万博客系统的的过程中,前面主要分享了爬虫.缓存穿透以及文章阅读量计数等等.爬虫的目的就是解决十万+问题:缓存穿透是为了保护后端数据库查询服务:计数服务解决了接近真实阅读数以及数据库服务的 ...

  8. 高可用服务设计之二:Rate limiting 限流与降级

    <高可用服务设计之二:Rate limiting 限流与降级> <nginx限制请求之一:(ngx_http_limit_conn_module)模块> <nginx限制 ...

  9. spring cloud gateway 之限流篇

    转载请标明出处: https://www.fangzhipeng.com 本文出自方志朋的博客 在高并发的系统中,往往需要在系统中做限流,一方面是为了防止大量的请求使服务器过载,导致服务不可用,另一方 ...

随机推荐

  1. 是否可以从一个静态(static)方法内部发出对非静态 (non-static)方法的调用?

    不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,在 调用静态方法时可能对象并没有被初始化.

  2. 学习Kvm(四)

    安装KVM虚拟化 1.系统基础环境: [root@linux-node1 ~]# ip addr | grep inet | awk '{ print $2; }' | sed 's/\/.*$//' ...

  3. Python - time标准库使用与程序计时

  4. Markdown语法1

    Markdown是一种轻量级标记语言. Markdown 编写的文档可以导出 HTML .Word.图像.PDF.Epub 等多种格式的文档. Markdown 编写的文档后缀为 .md, .mark ...

  5. C++ | 动多态的发生时机

    探究动多态的发生时机 有了虚函数和虚函数表为动多态提供支持,从而可以实现C++语言的动多态.那么,问题又来了. 动多态的发生时机是什么? 或者说,动多态发生有哪些条件与限制呢? 下面让我们一起来探究动 ...

  6. 【转自百度fex】fex-team/interview-questions

    fex-team/interview-questions 注意 目前发现有其他人以 FEX 团队名义进行招聘,发出的邮箱皆为私人邮箱. 为防止在投递简历出现误会,在此提醒各位注意: FEX 团队没有以 ...

  7. Episode 1:正视微信(试播)

    本期是 WEB VIEW 的第一期播客节目. 「不囿于 WEB,不止于 VIEW」,WEB VIEW 是由 yin 和敬礼主持的一档泛科技播客.节目中我们谨慎考量技术进步所带来的优缺点,提倡用「人治」 ...

  8. python-班级人员信息统计

    输入a,b班的名单,并进行如下统计. 输入格式: 第1行::a班名单,一串字符串,每个字符代表一个学生,无空格,可能有重复字符.第2行::b班名单,一串字符串,每个学生名称以1个或多个空格分隔,可能有 ...

  9. Canvas 制作海报

      HTML <template> <view class="content"> <view class="flex_row_c_c mod ...

  10. java中Object类的getClass方法有什么用以及怎么使用?

    Object类的getClass的用法: Object类中有一个getClass方法,m  a  r  k- t  o- w i n:它会返回一个你的对象所对应的一个Class的对象,这个返回来的对象 ...