FastMovieAI AI短剧创作平台 二开基线
- 源码: xhadmincn/FastMovieAI (Apache 2.0) - 二开: Docker部署, Swoole改Select, route.php修复, 补update/VERSION - vendor/示例资源已gitignore
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
local function get_script_dir()
|
||||
local lfs_ok, lfs = pcall(require, "lfs")
|
||||
|
||||
local source
|
||||
if debug and debug.getinfo then
|
||||
-- OpenResty 或标准 Lua 都适用
|
||||
source = debug.getinfo(2, "S").source:sub(2)
|
||||
elseif arg and arg[0] then
|
||||
source = arg[0]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 如果是相对路径,转换为绝对路径
|
||||
if not source:match("^/") then
|
||||
if lfs_ok then
|
||||
source = lfs.currentdir() .. "/" .. source
|
||||
else
|
||||
-- 没有 lfs,使用 io.popen("pwd") 获取当前目录
|
||||
local handle = io.popen("pwd")
|
||||
local cwd = handle:read("*l")
|
||||
handle:close()
|
||||
source = cwd .. "/" .. source
|
||||
end
|
||||
end
|
||||
|
||||
-- 提取目录
|
||||
local dir = source:match("(.*/)")
|
||||
return dir
|
||||
end
|
||||
|
||||
package.path = package.path .. ";"..get_script_dir().."module/?.lua;"
|
||||
-- 如过不是以/app/开头的请求,不进行QPS控制
|
||||
local request_uri = ngx.var.request_uri
|
||||
if not string.match(request_uri, "^/app/") then
|
||||
return
|
||||
end
|
||||
|
||||
-- 获取请求方法
|
||||
local method = ngx.req.get_method()
|
||||
method=tostring(method)
|
||||
|
||||
-- 获取请求路径
|
||||
local path = string.match(request_uri, "([^?]*)")
|
||||
path=tostring(path)
|
||||
|
||||
local env = require("load_env")
|
||||
-- 连接Redis
|
||||
local redis = require "resty.redis"
|
||||
local red = redis:new()
|
||||
red:set_timeout(1000) -- 1 秒超时
|
||||
|
||||
local ok, err = red:connect(env.get("REDIS_HOST","127.0.0.1"), env.get("REDIS_PORT",6379,"number"))
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR,"Connection to Redis failed: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
local database = env.get("REDIS_DATABASE",2,"number")
|
||||
-- 选择数据库
|
||||
local ok,err = red:select(database)
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR,"Failed to select Redis database ",database,": ", err)
|
||||
return
|
||||
end
|
||||
|
||||
-- 获取请求限制
|
||||
local limit_key="QPS:"..method..":"..path
|
||||
local limit, err = red:get(limit_key)
|
||||
limit = tonumber(limit)
|
||||
|
||||
-- 如果没有设置限制,则不进行QPS控制
|
||||
if not limit then
|
||||
return
|
||||
end
|
||||
|
||||
-- 获取请求头中的Authorization
|
||||
local authorization=ngx.var.http_authorization
|
||||
if not authorization then
|
||||
ngx.log(ngx.ERR,"The request header does not include Authorization: ",authorization)
|
||||
return ngx.exit(401)
|
||||
end
|
||||
|
||||
-- 拼接用户key
|
||||
authorization=tostring(authorization)
|
||||
local user_key = limit_key..":"..authorization
|
||||
|
||||
-- 获取用户请求次数
|
||||
local requests, err = red:get(user_key)
|
||||
requests = tonumber(requests)
|
||||
|
||||
if not requests then
|
||||
requests = 0
|
||||
end
|
||||
|
||||
-- 如果请求次数超过限制,则返回503
|
||||
if requests > limit then
|
||||
ngx.log(ngx.ERR,limit,"qps/s, Authorization: ",authorization)
|
||||
return ngx.exit(429)
|
||||
end
|
||||
|
||||
|
||||
-- 原子增加请求次数
|
||||
local ok, err = red:incr(user_key)
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR,"Redis increment operation failed: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
local ok, err = red:expire(user_key, 1)
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR,"Failed to set expiration for Redis key: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
-- 释放连接(连接池实现)
|
||||
local ok, err = red:set_keepalive(10000, 100)
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR,"Failed to set keepalive: ", err)
|
||||
return
|
||||
end
|
||||
Reference in New Issue
Block a user