https://blog.csdn.net/wyfhist/article/details/78333671

nginx+lua 限制接口访问次数
2017-10-24 19:54:32 三月软件----王耀峰 阅读数 4265更多
分类专栏: nginx lua
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wyfhist/article/details/78333671
最近看了一些nginx+lua 的东西,尝试实现了一下限流脚本,只包含最根本的功能。

代码如下

access_nginx_check.lua
-- 一个按照 url + 参数 进行 在固定时间内访问次数次数限制的lua 脚本,
-- 此处仅仅实现 按照url 10s 内限制 2次访问,记录每次访问次数(无用仅仅用于核对代码逻辑可去除),获取参数函数已有,后续需要完善

--package.path = package.path ..';..\?.lua';
--dofile ("./log.lua")
--是否开启检测
local check = "on"
--限制最大访问量
local count = 2
--限制时间范围
local seconds = 10
--获取参数的值
function getParam()
if "GET" == request_method then
args = ngx.req.get_uri_args()
elseif "POST" == request_method then
ngx.req.read_body()
args = ngx.req.get_post_args()
end
return args
end
--写入日志
function writerLog(str)
local time = os.time()
local date = os.date("%Y%m%d",time)

local file = io.open("/var/www/lua/logTest/"..tostring(date).."_log.log","a")
--ngx.say("/var/www/lua/log/"..tostring(date).."_log.log")
--assert(file)
file:write(str.."\n")
file:close();

end
--对uri 进行限制主要逻辑
function access_user_uri_check()
-- body
if check=="on" then
local access_uri = ngx.var.host..ngx.var.uri
--local param = getParam()
local key = accessuri
--提前在nginx中声明的变量
local limit = ngx.shared.limit
local req
if limit then
req ,
= limit:get(key)
end
if req then
if req>=count then
--超过限制之后返回错误
ngx.say("您在最近:"..seconds.."秒,访问:"..access_uri.."次数超过:"..count.."次,已经触发保护机制,请稍后访问")
ngx.exit(403)
end
--对key对应的数据进行累加
limit:incr(key,1)

    else

--没有值设置初始为1
limit:set(key,1,seconds)
end
--记录log
writerLog(key..":"..limit:get(key))

end

end
--错误调试函数
function myerrorhandler( err )
ngx.say( "ERROR:", err )
end
--测试代码,可以自动执行
status = xpcall( access_user_uri_check, myerrorhandler )
--access_user_uri_check()

对应nginx 配置
#声明变量 对应lua 脚本中 的ngx.shared.limit
lua_shared_dict limit 10m;
server{
listen 80;
server_name localhost.accesslua.com;
root /var/www/html/test;
charset utf-8;
location ~.php{
#为了调试lua脚本,直接将信息抛出到浏览器,否则会自动下载
default_type 'text/html';
#嵌入的lua脚本
access_by_lua_file "/var/www/lua/access_nginx_check.lua";
#php 的正常调用
fastcgi_pass 192.168.33.11:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
#记录log
access_log /usr/local/var/log/lua.accesslua-php5.access.log main;

}

演示效果