基于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. spring-boot-learning-REST风格网站

    什么是REST风格: Representational State Transfer :表现层状态转换,实际上是一种风格.标准,约定 首先需要有资源才能表现, 所以第一个名词是" 资源&qu ...

  2. 面试问题之C++语言:C与C++的区别

    C是C++的基础,C++语言和C语言在很多方面是兼容的. C是结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出或实现过程(事务 ...

  3. 学习FastDfs(四)

    1.简介 FastDFS 是一个开源的高性能分布式文件系统(DFS). 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡.主要解决了海量数据存储问题,特别适合以中小文件(建议范围: ...

  4. 学习RabbitMQ(二)

    MOM(message oriented middleware) 消息中间件(是在消息的传递过程中保存消息的容器,消息中间件再将消息从它的源中继到它的目标时,充当中间人的作用,队列的主要目的是提供路由 ...

  5. 集合学习之"将集合对象List<Product>转换为Map"

    将集合对象List<Product>转换为Map key = Product对象的sku value =Product对象 1 List<Product> products = ...

  6. swagger的作用和配置使用

    纯API项目中 引入swagger可以生成可视化的API接口页面     引入包 nuget包: Swashbuckle.AspNetCore(最新稳定版) 配置 1.配置Startup类Config ...

  7. 动态规划 洛谷P1048 [NOIP2005 普及组] 采药

    洛谷P1048 [NOIP2005 普及组] 采药 洛谷的一个谱架-的题目,考的是01背包问题,接下来分享一下我的题解代码. AC通过图: 我的代码: 1 //动态规划 洛谷P1048 [NOIP20 ...

  8. Leetcode刷题之矩阵中的指针用法

    矩阵中的指针用法 1 快慢指针 ​ Leetcode27移除元素 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度.不要使用额外的数组 ...

  9. word中怎么加入endnote的插件

    首先,打开Microsoft Word 2010,然后点击文件菜单,在弹出的项目中点击选项. 2 弹出Word选项对话框,在左侧导航处点击"加载项"按钮,如图. 3 在右侧内容窗口 ...

  10. 原来 flexbox 是这么工作的

    Flexbox 是一种 CSS 布局机制,可以说是目前浏览器原生支持的最好.使用最广泛的布局机制了.本文通过一些例子来说明 Flexbox 布局的工作原理,可以让我们更好的使用 Flexbox. 与 ...