route_table.lua 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. --
  2. -- Copyright 2019 The FATE Authors. All Rights Reserved.
  3. --
  4. -- Licensed under the Apache License, Version 2.0 (the "License");
  5. -- you may not use this file except in compliance with the License.
  6. -- You may obtain a copy of the License at
  7. --
  8. -- http://www.apache.org/licenses/LICENSE-2.0
  9. --
  10. -- Unless required by applicable law or agreed to in writing, software
  11. -- distributed under the License is distributed on an "AS IS" BASIS,
  12. -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. -- See the License for the specific language governing permissions and
  14. -- limitations under the License.
  15. --
  16. local ngx = ngx
  17. local new_timer = ngx.timer.at
  18. local yaml_parser = require "yaml_parser"
  19. local io = io
  20. local string = require "string"
  21. local _M = {
  22. _VERSION = '0.1'
  23. }
  24. -- alternatively: local lrucache = require "resty.lrucache.pureffi"
  25. local lrucache = require "resty.lrucache"
  26. -- we need to initialize the cache on the lua module level so that
  27. -- it can be shared by all the requests served by each nginx worker process:
  28. local route_cache, err = lrucache.new(500) -- allow up to 500 items in the cache
  29. if not route_cache then
  30. error("failed to create the cache: " .. (err or "unknown"))
  31. end
  32. local function reload_route_table()
  33. ngx.log(ngx.INFO, "start reload route table config")
  34. local prefix_path = ngx.config.prefix()
  35. local route_table_config_path = prefix_path.."conf/route_table.yaml"
  36. local file = io.open(route_table_config_path, "r")
  37. local content = file:read("*a")
  38. file:close()
  39. ngx.log(ngx.INFO, string.format("load route table config %s success", route_table_config_path))
  40. local yaml_table = yaml_parser.parse(content)
  41. for k, v in pairs(yaml_table) do
  42. route_cache:set(tostring(k), v)
  43. end
  44. ngx.log(ngx.INFO, "reload route table done")
  45. end
  46. local function reload()
  47. reload_route_table()
  48. local ok, err = new_timer(5, reload)
  49. if not ok then
  50. if err ~= "process exiting" then
  51. errlog("failed to create timer: ", err)
  52. end
  53. reload_route_table()
  54. return
  55. end
  56. end
  57. local function get_server_address(server)
  58. local port
  59. if ngx.req.http_version() == 2 then
  60. port = server["grpc_port"]
  61. else
  62. ngx.log(ngx.INFO, server["http_port"])
  63. port = server["http_port"]
  64. end
  65. return string.format("%s:%s", server["host"], port)
  66. end
  67. function _M.get_dest_server(dest_env, dest_service)
  68. ngx.log(ngx.INFO, string.format("try to get %s %s server", dest_env, dest_service))
  69. if dest_env ~= nil then
  70. dest_env = tostring(dest_env)
  71. else
  72. return nil
  73. end
  74. local route = _M.get_route()
  75. local env_services = route:get(dest_env)
  76. local server
  77. if env_services ~= nil then
  78. local service = env_services[dest_service]
  79. server = get_server_address(service[math.random(1, #service)])
  80. ngx.log(ngx.INFO, string.format("get %s %s server: %s", dest_env, dest_service, server))
  81. else
  82. local default_proxy = route:get("default")["proxy"]
  83. server = get_server_address(default_proxy[math.random(1, #default_proxy)])
  84. ngx.log(ngx.INFO, string.format("get %s %s default server: %s", dest_env, dest_service, server))
  85. end
  86. return server
  87. end
  88. function _M.get_route()
  89. return route_cache
  90. end
  91. function _M.start()
  92. reload()
  93. end
  94. return _M