tenant_router.lua 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. local redis = require "resty.redis"
  2. -- 定义Redis连接参数
  3. local REDIS_HOST = "redis-host"
  4. local REDIS_PORT = 6379
  5. local REDIS_TIMEOUT = 1000 -- 1秒超时
  6. local ngx_shared = ngx.shared
  7. local env_cache = ngx_shared.env_cache -- 需在nginx.conf定义共享内存lua_shared_dict env_cache 10m;
  8. local _M = {}
  9. -- 设置后端upstream
  10. function set_upstream(tenant, env)
  11. if env == "prod" then
  12. ngx.var.upstream = "backend_prod"
  13. elseif env == "dev" then
  14. ngx.var.upstream = "backend_dev"
  15. else
  16. ngx.log(ngx.ERR, "Upstream not found for env: " .. tostring(env))
  17. return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码
  18. end
  19. ngx.log(ngx.INFO, "Backend routing: ", "tenant=", tenant, "env=", env, ", upstream=", ngx.var.upstream)
  20. end
  21. -- 设置前端upstream
  22. function set_frontend_upstream(tenant, env)
  23. if env == "prod" then
  24. ngx.var.frontend_upstream = "frontend_prod"
  25. elseif env == "dev" then
  26. ngx.var.frontend_upstream = "frontend_dev"
  27. else
  28. ngx.log(ngx.ERR, "Frontend upstream not found for env: " .. tostring(env))
  29. return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码
  30. end
  31. ngx.log(ngx.INFO, "Frontend routing: ", "tenant=", tenant, "env=", env, ", frontend_upstream=", ngx.var.frontend_upstream)
  32. end
  33. -- 根据租户信息获取环境变量
  34. function get_env(tenant)
  35. local cache_key = "tenant_identification_location_" .. tenant
  36. local cache_res = env_cache:get(cache_key)
  37. if cache_res then
  38. ngx.log(ngx.DEBUG, "Cache hit: ", cache_key)
  39. return cache_res
  40. end
  41. local red = redis:new()
  42. red:set_timeouts(REDIS_TIMEOUT, REDIS_TIMEOUT, REDIS_TIMEOUT)
  43. local ok, connect_err = red:connect(REDIS_HOST, REDIS_PORT)
  44. if not ok then
  45. ngx.log(ngx.ERR, "Redis connect failed: ", connect_err)
  46. return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) -- 使用标准HTTP状态码
  47. end
  48. local env = red:get(cache_key)
  49. if not env then
  50. ngx.log(ngx.ERR, "No environment found for tenant:", tenant)
  51. red:set_keepalive(10000, 100) -- 归还连接到连接池
  52. return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) -- 使用标准HTTP状态码
  53. end
  54. red:set_keepalive(10000, 100)
  55. env_cache:set(cache_key, env, 60) -- 缓存60秒
  56. return env
  57. end
  58. -- 处理API请求的路由逻辑
  59. function _M.route_by_tenant_for_api()
  60. local tenant = ngx.req.get_headers()["X-Tenant"] or ngx.req.get_uri_args()["tenant"]
  61. if not tenant or tenant == "" then
  62. ngx.log(ngx.ERR, "Missing tenant identifier")
  63. return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码
  64. end
  65. local env = get_env(tenant)
  66. set_upstream(tenant, env)
  67. end
  68. -- 处理前端请求的路由逻辑
  69. function _M.route_by_tenant_for_frontend()
  70. local tenant = ngx.req.get_headers()["X-Tenant"] or ngx.req.get_uri_args()["tenant"]
  71. if not tenant or tenant == "" then
  72. ngx.log(ngx.ERR, "Missing tenant identifier")
  73. return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码
  74. end
  75. local env = get_env(tenant)
  76. set_frontend_upstream(env)
  77. end
  78. return _M