ngx-lua实现高级限流方式一
基于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; # 指定项目根目录
}
}
核心解读
获取请求体
- POST请求
- JSON格式
- 获取不到不能影响其他阶段继续执行
解析请求体获取目标参数
- cjson.decode()
- 操作map获取目标数据(限流的指标)
- 获取不到不能影响其他阶段继续执行
确定限流方式
- 限请求速率
- 限连接数
ngx-lua实现高级限流方式一的更多相关文章
- Lua学习高级篇
Lua学习高级篇 之前已经说了很多,我目前的观点还是那样,在嵌入式脚本中,Lua是最优秀.最高效的,如果您有不同的观点,欢迎指正并讨论,切勿吐槽.这个系列完全来自于<Programming in ...
- ngx.lua中遇到的小问题2
用lua+drizzle在数据库中插入数据失败(不能访问数据库) 后面发现原来是nginx配置文件中的drizzle模块部分最后多了一行 content_by_lua 'ngx.say(" ...
- ngx.lua中遇到的小问题
作者: 胡 志伟 分类: ngx_lua, 开发代码 发布时间: 2013-09-26 08:40 ė 6评论关闭 在使用ngx.redirect 到一个新的地址时,错误日志提示: lua entry ...
- java并发系列 - 第29天:高并发中常见的限流方式
这是java高并发系列第29篇. 环境:jdk1.8. 本文内容 介绍常见的限流算法 通过控制最大并发数来进行限流 通过漏桶算法来进行限流 通过令牌桶算法来进行限流 限流工具类RateLimiter ...
- ngx lua获取时间戳的几种方式
原创自由de单车 最后发布于2017-02-14 14:58:43 阅读数 18218 收藏 在ngx_lua里,获取时间相关信息的方式大概有4种(见下面代码): print(string.forma ...
- Spring Cloud Alibaba | Sentinel: 服务限流高级篇
目录 Spring Cloud Alibaba | Sentinel: 服务限流高级篇 1. 熔断降级 1.1 降级策略 2. 热点参数限流 2.1 项目依赖 2.2 热点参数规则 3. 系统自适应限 ...
- 从SpringBoot构建十万博文聊聊限流特技
前言 在开发十万博客系统的的过程中,前面主要分享了爬虫.缓存穿透以及文章阅读量计数等等.爬虫的目的就是解决十万+问题:缓存穿透是为了保护后端数据库查询服务:计数服务解决了接近真实阅读数以及数据库服务的 ...
- 高可用服务设计之二:Rate limiting 限流与降级
<高可用服务设计之二:Rate limiting 限流与降级> <nginx限制请求之一:(ngx_http_limit_conn_module)模块> <nginx限制 ...
- spring cloud gateway 之限流篇
转载请标明出处: https://www.fangzhipeng.com 本文出自方志朋的博客 在高并发的系统中,往往需要在系统中做限流,一方面是为了防止大量的请求使服务器过载,导致服务不可用,另一方 ...
随机推荐
- vue集成CKEditor构建框架的使用,遇到富文本框不出现工具栏等操作
官方关于Vue集成CKEditor富文本框的文档:https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/framew ...
- Java如何声明一个数组?JS如何声明一个数组?如何获取数组长度
1 Long[] numbers; //一般使用的定义方式,可分为静态和动态两种定义方式,下有说明. 2 Long numbers[]; //跟上面用法一致. 3 Long... numbers; / ...
- 数据分析之Numpy的基本操作
Numpy NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库. 1 创建 ndarray 使 ...
- 学习MFS(三)
1.MooseFS是什么 一个类MooseFS是一个具备冗余容错功能的分布式网络文件系统,它将数据分别存放在多个物理服务器或单独磁盘或分区上,确保一份数据有多个备份副本,然而对于访问MFS的客户端或者 ...
- 关于elementUI如何在表格循环列表里分别新增Tag的设计使用
话不多说,直接上代码.想要实现的目的是这样的,想要在表格里单独添加每一个tag 那么,需要解决的问题就是如何定义这每一个插槽里的输入框,把每个输入框以及里面插入的数据区分开. 研究了很久,最后选择了对 ...
- ROS学习文章
ros机器人到底有没有必要学习?
- 判断1~n有多少个1
判断1~n有多少个1 例如:1~12中 1 2 3 4 5 6 7 8 9 10 11 12 有1,10,11,12中含有1,则共有5个1: 算法如下: #include<stdio.h> ...
- [转载] Link prefetch
本来想翻译的但是有人翻译了,还是转过来吧.原文<HTML5 Link Prefetching>,译文<使用HTML5的页面资源预加载(Link prefetch)功能加速你的页面加载 ...
- 关于Css的垂直居中的一些方法
前两种方法称为大致居中,一般误差随高度的减小而减小,不过一般来说不怎么看得出来,除非你用javascript调用offsetTop来查看.不然没有强迫症的比较难看出来.但是兼容性很好,尤其是table ...
- css盒子模型、垂直外边距合并
css盒子模型由四部分组成:内容(content).填充(padding).边框(border).边距(margin),其中css样式中定义的width属性是定义内容区域的宽度,正常情况下,设置了内容 ...