resty-limit-multiple-strategy.lua
--[[
执行过载限流策略
--]] -- 当执行限流时,Nginx 返回的状态码
err_code = local limit_config = {
user_limit = {rate = , brust = }, --用户限流维度桶设置
priority_uri_limit = { --指定 URI 限流维度桶设置
['/elis_smp_portal_dmz/do/cms/getLittleRedDotInfo'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/esa/portal.msgcenter.unreadv2'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/home/getUpgradeReminder'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/userLogin/checkPluginVersion'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/createRYMSession'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/zone/queryZoneConfig'] = {rate = , brust = }
},
error_status = err_code, --请求被限流时返回状态码
nodelay = no --是否需要不延迟处理
} --定义限流策略方法名称
local limit_user_method = "limit_by_user"
local limit_uri_method = "limit_by_priority_uri" local limit_req = require "resty.limit.req" ngx.req.read_body() --过载保护策略总开关,若开关关闭,则全部策略失效
local limit_req_store = ngx.shared.limit_req_store
local overload_protection_switch = limit_req_store:get("overload_protection_switch")
if (overload_protection_switch ~= nil and overload_protection_switch == "N") then
ngx.log(ngx.INFO, "nginx limit strategy has been shutdown.")
return
end -- 获取当前请求 URI
local cur_uri = ngx.var.uri -- 执行过载操作
local is_in_black_list = limit_req_store:get("black_list:"..cur_uri)
local is_rejected_uri = reject_uri_tab["rejected"..cur_uri]
if (is_in_black_list ~= nil or is_rejected_uri ~= nil) then
-- 拦截比例,默认全部拦截
local request_limit_percent = limit_req_store:get("reject_request_percent")
if request_limit_percent == nil then
request_limit_percent =
end
local random_num = math.random()
if random_num <= tonumber(request_limit_percent) then
ngx.log(ngx.ERR,"nginx limit strategy current uri=",cur_uri," has been rejected.")
ngx.exit(ngx.HTTP_FORBIDDEN)
end
end -- 执行限流策略,入参:key 和 commit,commit 默认为 true
local function execute_limit_strategy(lim, key, commit, method)
-- 请求流入,如果你的请求需要被延迟则返回delay>0
local delay, err = lim:incoming(key, commit)
if (not delay and err == "rejected") then
ngx.log(ngx.ERR, "nginx limit strategy: ",method,", key: ", key, " request rate was exceeded, current request was rejected.")
ngx.exit(limit_config.error_status)
end -- 根据需要决定延迟或者不延迟处理
if delay > then
if limit_config.nodelay then
-- 直接突发处理
-- ngx.log(ngx.ERR, "nginx limit strategy: ", method, ", key: ", key, " request rate was exceeded, current request was rejected. delay")
-- ngx.exit(error_status)
else
--延迟处理
ngx.sleep(delay)
end
end
end -- 获取限流策略的共享内存
local function get_shared_dict(shared_dict_name, rate, burst)
local limit_shared_dict, err = limit_req.new(shared_dict_name, rate, burst)
if not limit_shared_dict then --没定义共享字典
ngx.log(ngx.ERR, "Nginx limit shared dict:", shared_dict_name, " has not been set.")
ngx.exit(error_status)
end
return limit_shared_dict
end -- 初始化 URL 限流策略 table
local uri_limit_tab = {} local user_lim if limit_config == nil then
ngx.log(ngx.ERR, "nginx request limit has no config info.")
return
else
local user_limit_config = limit_config.user_limit
ngx.log(ngx.DEBUG,"limit config user rate:", user_limit_config.rate, ", brust:", user_limit_config.brust)
user_lim = get_shared_dict("limit_req_store",user_limit_config.rate, user_limit_config.brust)
local priority_uri_limit_config = limit_config.priority_uri_limit
for key, value in pairs(priority_uri_limit_config) do
local rate = value.rate
local brust = value.brust
ngx.log(ngx.DEBUG,"limit config uri:", key, ", rate:", rate,", brust:",brust)
local lim = get_shared_dict("limit_req_store",rate,brust)
uri_limit_tab[key]=lim
end
end -- 执行指定 URI 限流策略
if uri_limit_tab[cur_uri] ~= nil then
execute_limit_strategy(uri_limit_tab[cur_uri], cur_uri , true , limit_uri_method)
end -- 获取客户端请求 IP
local remote_ip = ngx.var.remote_addr
local user_id
local device_id
local key_by_user -- 获取用户ID 或 设备号
local request_method = ngx.var.request_method
if "GET" == request_method then
user_id = ngx.req.get_uri_args()["uid"]
device_id = ngx.req.get_uri_args()["deviceId"]
ngx.log(ngx.DEBUG, "nginx request limit module GET parameter user_id: ",user_id, " header:",device_id)
elseif "POST" == request_method then
-- 获取请求头信息,如果缺少请求头信息判断,遇到上传文件操作时,会引起ngx.req.get_post_args()操作异常。
local receive_headers = ngx.req.get_headers()
local body_data = ngx.req.get_body_data()
if not body_data or (receive_headers["content-type"] ~= nil and string.sub(receive_headers["content-type"],,) == "multipart/form-data;") then
ngx.log(ngx.WARN,"nginx request limit module uri: ",cur_uri, " header:",receive_headers["content-type"],", body data:",body_data)
return
end
user_id = ngx.req.get_post_args()['uid'];
device_id = ngx.req.get_post_args()['deviceId'];
ngx.log(ngx.DEBUG, "nginx request limit module POST parameter user_id: ",user_id, " device_id:",device_id)
end -- 调试日志
ngx.log(ngx.ERR, "nginx request limit module cur_uri:",cur_uri, ", user_id: ",user_id) if (user_id ~= nil or device_id ~= nil) then
if user_id ~= nil then
key_by_user = user_id
else
key_by_user = device_id
end
execute_limit_strategy(user_lim,key_by_user..":"..remote_ip, true, limit_user_method)
end
resty-limit-multiple-strategy.lua的更多相关文章
- nginx安装lua模块实现高并发
nginx安装lua扩展模块 1.下载安装LuaJIT-2.0.4.tar.gz wget -c http://luajit.org/download/LuaJIT-2.0.4.tar.gz tar ...
- nginx + lua 限制ip地址访问
实验环境:docker + openresty 我限制的5秒钟内允许访问两次效果图: default.conf 代码如下: lua_shared_dict my_limit_count_store ...
- OpenResty之 limit.count 模块
原文: lua-resty-limit-traffic/lib/resty/limit/count.md 1. 示例 http { lua_shared_dict my_limit_count_sto ...
- Openresty+Lua+Kafka实现日志实时采集
简介 在很多数据采集场景下,Flume作为一个高性能采集日志的工具,相信大家都知道它.许多人想起Flume这个组件能联想到的大多数都是Flume跟Kafka相结合进行日志的采集,这种方案有很多他的优点 ...
- 线程池Executors探究
线程池用到的类在java.util.concurrent包下,核心类是Executors,通过其不同的几个方法可产生不同的线程池. 1.生成固定大小的线程池 public static Executo ...
- Nginx执行阶段
Nginx 介绍 Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器. Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮 ...
- 又拍云张聪:OpenResty 动态流控的几种姿势
2019 年 1 月 12 日,由又拍云.OpenResty 中国社区主办的 OpenResty × Open Talk 全国巡回沙龙·深圳站圆满结束,又拍云首席架构师张聪在活动上做了< Ope ...
- 《用OpenResty搭建高性能服务端》笔记
概要 <用OpenResty搭建高性能服务端>是OpenResty系列课程中的入门课程,主讲人:温铭老师.课程分为10个章节,侧重于OpenResty的基本概念和主要特点的介绍,包括它的指 ...
- openresty/1.11.2.1性能测试
测试数据 ab -n -c -k http://127.0.0.1/get_cache_value nginx.conf lua_shared_dict cache_ngx 128m; server ...
随机推荐
- struts2 、mybatis 、easyui 分页
rows page 控件自动提交这两个参数 pageSize number The page size. 10pageNumber number Show the page number when p ...
- 【转】ANDROID自定义视图——onLayout源码 流程 思路详解
转载(http://blog.csdn.net/a396901990) 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量——onMeasure():决定View的大小 2.布局 ...
- 【C#】MVC+EF+LINQ 综合小项目
第一,创建数据库 create table category(id int primary key,name nvarchar(20)) create table news(id int primar ...
- .Net Core 项目引用本地类库方式(一)
最近了解到.NET Core 项目,引用本地类库DLL的方式有三种 1.非同解决方案下的引用,直接引用,浏览,找到对应的DLL,然后确定引用. 这种方式有个不好的地方就是,如果引用的DLL文件里面,也 ...
- { "result": null, "log_id": 304592860300941982, "error_msg": "image check fail", "cached": 0, "error_code": 222203, "timestamp": 1556030094 }
这个是人脸识别时无法检测到图片报的错,有时候我们检测一张图片是否在库里面,当一张图片明显在里面,还检测不到,如下面是我的代码 package Test1; import java.io.IOExcep ...
- 用python写个快排
快排过程比较简单就直接上代码了: #!/usr/bin/python3 def quik_sort(L, left, right): if left <= right: key = L[left ...
- GN算法---《Community structure in social and biological networks》这篇论文讲了什么?
用中文记下这篇论文的大致意思,以防止忘了.好记性不如烂笔头! 摘要:最近的一些研究在研究社交网络或WWW.研究者都集中于研究网络的“小世界性”,“幂率分布特性”,“网络传递性”(聚类性吧).本文提出网 ...
- 【算法】关于图论中的最小生成树(Minimum Spanning Tree)详解
本节纲要 什么是图(network) 什么是最小生成树 (minimum spanning tree) 最小生成树的算法 什么是图(network)? 这里的图当然不是我们日常说的图片或者地图.通常情 ...
- TX1 文字界面启动与root用户自动登录设置
设置默认文字启动界面 更改/boot/extlinux/extlinux.conf文件,在最后一行的末尾添加 text. 设置自动登录 在/etc/init/tty1.conf文件末尾添加: exec ...
- 【解决】Linux Tomcat启动慢--Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [236,325] milliseconds
一.背景 今天部署项目到tomcat,执行./startup.sh命令之后,访问项目迟迟加载不出来,查看日志又没报错(其实是我粗心了,当时tomcat日志还没打印完),一开始怀疑是阿里云主机出现问题, ...