local redis = require "resty.redis" -- 定义Redis连接参数 local REDIS_HOST = "redis" local REDIS_PORT = 6379 local REDIS_PASSWORD = "secret_redis" local REDIS_TIMEOUT = 1000 -- 1秒超时 local _M = {} -- 设置后端upstream function set_upstream(tenant, env) if env == "prod" then ngx.var.upstream = "backend_prod" elseif env == "dev" then ngx.var.upstream = "backend_dev" else ngx.log(ngx.ERR, "Upstream not found for env: " .. tostring(env)) return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码 end ngx.log(ngx.NOTICE, "Backend routing: ", "tenant=", tenant, ", env=", env, ", upstream=", ngx.var.upstream) end -- 设置前端upstream function set_frontend_upstream(tenant, env) if env == "prod" then ngx.var.frontend_upstream = "frontend_prod" elseif env == "dev" then ngx.var.frontend_upstream = "frontend_dev" else ngx.log(ngx.ERR, "Frontend upstream not found for env: " .. tostring(env)) return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码 end ngx.log(ngx.NOTICE, "Frontend routing: ", "tenant=", tenant, ", env=", env, ", frontend_upstream=", ngx.var.frontend_upstream) end -- 根据租户信息获取环境变量 function get_env(tenant) local cache_key = "tenant_identification_location_" .. tenant local red = redis:new() red:set_timeouts(REDIS_TIMEOUT, REDIS_TIMEOUT, REDIS_TIMEOUT) -- 连接到Redis local ok, connect_err = red:connect(REDIS_HOST, REDIS_PORT) if not ok then ngx.log(ngx.ERR, "Redis connect failed: ", connect_err) return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) -- 使用标准HTTP状态码 end -- 认证Redis local ok, auth_err = red:auth(REDIS_PASSWORD) if not ok then ngx.log(ngx.ERR, "Failed to authenticate Redis: ", auth_err) return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- 选择数据库 0(默认数据库) local ok, err = red:select(0) if not ok then ngx.log(ngx.ERR, "Failed to select Redis database: ", err) return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end -- 从Redis中获取环境变量 local env = red:get(cache_key) if not env then ngx.log(ngx.ERR, "No environment found for tenant key: ", cache_key) red:set_keepalive(10000, 100) -- 归还连接到连接池 return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) -- 使用标准HTTP状态码 end red:set_keepalive(10000, 100) return env end -- 处理API请求的路由逻辑 function _M.route_by_tenant_for_api() local tenant = ngx.req.get_headers()["X-Tenant"] or ngx.req.get_uri_args()["tenant"] if not tenant or tenant == "" then ngx.log(ngx.ERR, "Missing tenant identifier") return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码 end local env = get_env(tenant) set_upstream(tenant, env) end -- 处理前端请求的路由逻辑 function _M.route_by_tenant_for_frontend() local tenant = ngx.req.get_headers()["X-Tenant"] or ngx.req.get_uri_args()["tenant"] if not tenant or tenant == "" then ngx.log(ngx.ERR, "Missing tenant identifier") return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码 end local env = get_env(tenant) set_frontend_upstream(env) end return _M