使用 OpenResty 可以不用再次编译nginx 就能集成对应lua环境 可以扩展的模块比较丰富
1.使用redis 控制限流 ip 访问频度
创建对应lua脚本 access_by_limit_frequency.lua
local function close_redis(red)
if not red then
return
end
--释放连接(连接池实现)
local pool_max_idle_time = 10000 --毫秒
local pool_size = 100 --连接池大小
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
if not ok then
ngx.say("set keepalive error : ", err)
end
end
local function errlog(...)
ngx.log(ngx.ERR, "redis: ", ...)
end
local redis = require "resty.redis" --引入redis模块
local red = redis:new() --创建一个对象,注意是用冒号调用的
--设置超时(毫秒)
red:set_timeout(1000)
--建立连接
local ip = "127.0.0.1"
local port = 6379
local ok, err = red:connect(ip, port)
if not ok then
close_redis(red)
errlog("Cannot connect");
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
local key = "limit:frequency:login:"..ngx.var.remote_addr
--得到此客户端IP的频次
local resp, err = red:get(key)
if not resp then
close_redis(red)
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis 获取值失败
end
if resp == ngx.null then
red:set(key, 1) -- 单位时间 第一次访问
red:expire(key, 10) --10秒时间 过期
end
if type(resp) == "string" then
if tonumber(resp) > 10 then -- 超过10次
close_redis(red)
return ngx.exit(ngx.HTTP_FORBIDDEN) --直接返回403
end
end
--调用API设置key
ok, err = red:incr(key)
if not ok then
close_redis(red)
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis 报错
end
close_redis(red)
2.在 nginx.conf 中配置对应的 路径的使用情况处理
location ^~/frequency/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# default_type 'text/plain';
# charset 'utf-8';
access_by_lua_file D:\openresty-1.15.8.3-win64\lua\local\access_by_limit_frequency.lua;
# content_by_lua '
# ngx.say(ngx.time() * 1000);
# ngx.exit(200)
# ';
# content_by_lua_block {
# ngx.say("{\"error\":0, \"status\":0,\"msg\":\"ok\"}");
# ngx.exit(200);
# }
root D:/ds_wechat_files;
}
以上是从其他地方找到的。大杂烩,如有侵权请联系我