tenant_router.lua 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. local redis = require "resty.redis"
  2. -- 定义Redis连接参数
  3. local REDIS_HOST = "redis"
  4. local REDIS_PORT = 6379
  5. local REDIS_PASSWORD = "secret_redis"
  6. local REDIS_TIMEOUT = 1000 -- 1秒超时
  7. local _M = {}
  8. -- 设置后端upstream
  9. function set_upstream(tenant, env)
  10. if env == "prod" then
  11. ngx.var.upstream = "php80_prod"
  12. ngx.var.root = "/www/autocde2.0_laravel_prod"
  13. elseif env == "dev" then
  14. ngx.var.upstream = "php80"
  15. ngx.var.upstream = "/www/autocde2.0_laravel"
  16. else
  17. ngx.log(ngx.ERR, "Upstream not found for env: " .. tostring(env))
  18. ngx.var.upstream = "php80_prod"
  19. ngx.var.upstream = "/www/autocde2.0_laravel_prod"
  20. end
  21. ngx.log(ngx.NOTICE, "Backend routing: ", "tenant=", tenant, ", env=", env, ", upstream=", ngx.var.upstream)
  22. end
  23. -- 设置前端upstream
  24. function set_frontend_upstream(tenant, env)
  25. if env == "prod" then
  26. ngx.var.frontend_upstream = "frontend_prod"
  27. elseif env == "dev" then
  28. ngx.var.frontend_upstream = "frontend_dev"
  29. else
  30. end
  31. ngx.log(ngx.NOTICE, "Frontend routing: ", "tenant=", tenant, ", env=", env, ", frontend_upstream=", ngx.var.frontend_upstream)
  32. end
  33. -- 根据租户信息获取环境变量
  34. function get_env(tenant)
  35. if not tenant then
  36. ngx.log(ngx.NOTICE, "Missing tenant identifier")
  37. tenant = "not_found"
  38. end
  39. local cache_key = "tenant_identification_location_" .. tenant
  40. local red = redis:new()
  41. red:set_timeouts(REDIS_TIMEOUT, REDIS_TIMEOUT, REDIS_TIMEOUT)
  42. -- 连接到Redis
  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. -- 认证Redis
  49. local ok, auth_err = red:auth(REDIS_PASSWORD)
  50. if not ok then
  51. ngx.log(ngx.ERR, "Failed to authenticate Redis: ", auth_err)
  52. return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
  53. end
  54. -- 选择数据库 0(默认数据库)
  55. local ok, err = red:select(0)
  56. if not ok then
  57. ngx.log(ngx.ERR, "Failed to select Redis database: ", err)
  58. return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
  59. end
  60. -- 从Redis中获取环境变量
  61. local env = red:get(cache_key)
  62. if not env then
  63. ngx.log(ngx.ERR, "No environment found for tenant key: ", cache_key)
  64. red:set_keepalive(10000, 100) -- 归还连接到连接池
  65. return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) -- 使用标准HTTP状态码
  66. end
  67. red:set_keepalive(10000, 100)
  68. return env
  69. end
  70. -- 处理API请求的路由逻辑
  71. function _M.route_by_tenant_for_api()
  72. local args = ngx.req.get_uri_args()
  73. local tenant = ngx.req.get_headers()["X-Tenant"] or args["tenant"]
  74. if not tenant or tenant == "" then
  75. ngx.log(ngx.ERR, "Missing tenant identifier")
  76. return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码
  77. end
  78. local env = get_env(tenant)
  79. set_upstream(tenant, env)
  80. end
  81. -- 处理前端请求的路由逻辑
  82. function _M.route_by_tenant_for_frontend()
  83. local args = ngx.req.get_uri_args()
  84. local tenant = ngx.req.get_headers()["X-Tenant"] or args["tenant"]
  85. if not tenant or tenant == "" then
  86. ngx.log(ngx.ERR, "Missing tenant identifier")
  87. -- return ngx.exit(ngx.HTTP_BAD_REQUEST) -- 使用标准HTTP状态码
  88. end
  89. local env = get_env(tenant)
  90. set_frontend_upstream(tenant, env)
  91. end
  92. return _M