Dynamic LB sync non-external backends only when necessary
This commit is contained in:
parent
10dcf0db15
commit
bcc3cfaa65
4 changed files with 91 additions and 6 deletions
|
@ -23,6 +23,7 @@ local ngx = ngx
|
||||||
-- it will take <the delay until controller POSTed the backend object to the
|
-- it will take <the delay until controller POSTed the backend object to the
|
||||||
-- Nginx endpoint> + BACKENDS_SYNC_INTERVAL
|
-- Nginx endpoint> + BACKENDS_SYNC_INTERVAL
|
||||||
local BACKENDS_SYNC_INTERVAL = 1
|
local BACKENDS_SYNC_INTERVAL = 1
|
||||||
|
local BACKENDS_FORCE_SYNC_INTERVAL = 30
|
||||||
|
|
||||||
local DEFAULT_LB_ALG = "round_robin"
|
local DEFAULT_LB_ALG = "round_robin"
|
||||||
local IMPLEMENTATIONS = {
|
local IMPLEMENTATIONS = {
|
||||||
|
@ -36,6 +37,8 @@ local IMPLEMENTATIONS = {
|
||||||
|
|
||||||
local _M = {}
|
local _M = {}
|
||||||
local balancers = {}
|
local balancers = {}
|
||||||
|
local backends_with_external_name = {}
|
||||||
|
local backends_last_synced_at = 0
|
||||||
|
|
||||||
local function get_implementation(backend)
|
local function get_implementation(backend)
|
||||||
local name = backend["load-balance"] or DEFAULT_LB_ALG
|
local name = backend["load-balance"] or DEFAULT_LB_ALG
|
||||||
|
@ -92,6 +95,12 @@ local function format_ipv6_endpoints(endpoints)
|
||||||
return formatted_endpoints
|
return formatted_endpoints
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function is_backend_with_external_name(backend)
|
||||||
|
local serv_type = backend.service and backend.service.spec
|
||||||
|
and backend.service.spec["type"]
|
||||||
|
return serv_type == "ExternalName"
|
||||||
|
end
|
||||||
|
|
||||||
local function sync_backend(backend)
|
local function sync_backend(backend)
|
||||||
if not backend.endpoints or #backend.endpoints == 0 then
|
if not backend.endpoints or #backend.endpoints == 0 then
|
||||||
balancers[backend.name] = nil
|
balancers[backend.name] = nil
|
||||||
|
@ -117,9 +126,7 @@ local function sync_backend(backend)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local service_type = backend.service and backend.service.spec
|
if is_backend_with_external_name(backend) then
|
||||||
and backend.service.spec["type"]
|
|
||||||
if service_type == "ExternalName" then
|
|
||||||
backend = resolve_external_names(backend)
|
backend = resolve_external_names(backend)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -129,6 +136,17 @@ local function sync_backend(backend)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sync_backends()
|
local function sync_backends()
|
||||||
|
local raw_backends_last_synced_at = configuration.get_raw_backends_last_synced_at()
|
||||||
|
ngx.update_time()
|
||||||
|
local current_timestamp = ngx.time()
|
||||||
|
if current_timestamp - backends_last_synced_at < BACKENDS_FORCE_SYNC_INTERVAL
|
||||||
|
and raw_backends_last_synced_at <= backends_last_synced_at then
|
||||||
|
for _, backend_with_external_name in pairs(backends_with_external_name) do
|
||||||
|
sync_backend(backend_with_external_name)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local backends_data = configuration.get_backends_data()
|
local backends_data = configuration.get_backends_data()
|
||||||
if not backends_data then
|
if not backends_data then
|
||||||
balancers = {}
|
balancers = {}
|
||||||
|
@ -145,13 +163,19 @@ local function sync_backends()
|
||||||
for _, new_backend in ipairs(new_backends) do
|
for _, new_backend in ipairs(new_backends) do
|
||||||
sync_backend(new_backend)
|
sync_backend(new_backend)
|
||||||
balancers_to_keep[new_backend.name] = balancers[new_backend.name]
|
balancers_to_keep[new_backend.name] = balancers[new_backend.name]
|
||||||
|
if is_backend_with_external_name(new_backend) then
|
||||||
|
local backend_with_external_name = util.deepcopy(new_backend)
|
||||||
|
backends_with_external_name[backend_with_external_name.name] = backend_with_external_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for backend_name, _ in pairs(balancers) do
|
for backend_name, _ in pairs(balancers) do
|
||||||
if not balancers_to_keep[backend_name] then
|
if not balancers_to_keep[backend_name] then
|
||||||
balancers[backend_name] = nil
|
balancers[backend_name] = nil
|
||||||
|
backends_with_external_name[backend_name] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
backends_last_synced_at = raw_backends_last_synced_at
|
||||||
end
|
end
|
||||||
|
|
||||||
local function route_to_alternative_balancer(balancer)
|
local function route_to_alternative_balancer(balancer)
|
||||||
|
|
|
@ -24,6 +24,14 @@ function _M.get_general_data()
|
||||||
return configuration_data:get("general")
|
return configuration_data:get("general")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _M.get_raw_backends_last_synced_at()
|
||||||
|
local raw_backends_last_synced_at = configuration_data:get("raw_backends_last_synced_at")
|
||||||
|
if raw_backends_last_synced_at == nil then
|
||||||
|
raw_backends_last_synced_at = 1
|
||||||
|
end
|
||||||
|
return raw_backends_last_synced_at
|
||||||
|
end
|
||||||
|
|
||||||
local function fetch_request_body()
|
local function fetch_request_body()
|
||||||
ngx.req.read_body()
|
ngx.req.read_body()
|
||||||
local body = ngx.req.get_body_data()
|
local body = ngx.req.get_body_data()
|
||||||
|
@ -187,6 +195,16 @@ local function handle_backends()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ngx.update_time()
|
||||||
|
local raw_backends_last_synced_at = ngx.time()
|
||||||
|
success, err = configuration_data:set("raw_backends_last_synced_at", raw_backends_last_synced_at)
|
||||||
|
if not success then
|
||||||
|
ngx.log(ngx.ERR, "dynamic-configuration: error updating when backends sync, " ..
|
||||||
|
"new upstream peers waiting for force syncing: " .. tostring(err))
|
||||||
|
ngx.status = ngx.HTTP_BAD_REQUEST
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
ngx.status = ngx.HTTP_CREATED
|
ngx.status = ngx.HTTP_CREATED
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ local getmetatable = getmetatable
|
||||||
-- it will take <the delay until controller POSTed the backend object
|
-- it will take <the delay until controller POSTed the backend object
|
||||||
-- to the Nginx endpoint> + BACKENDS_SYNC_INTERVAL
|
-- to the Nginx endpoint> + BACKENDS_SYNC_INTERVAL
|
||||||
local BACKENDS_SYNC_INTERVAL = 1
|
local BACKENDS_SYNC_INTERVAL = 1
|
||||||
|
local BACKENDS_FORCE_SYNC_INTERVAL = 30
|
||||||
|
|
||||||
local DEFAULT_LB_ALG = "round_robin"
|
local DEFAULT_LB_ALG = "round_robin"
|
||||||
local IMPLEMENTATIONS = {
|
local IMPLEMENTATIONS = {
|
||||||
|
@ -26,6 +27,8 @@ local IMPLEMENTATIONS = {
|
||||||
|
|
||||||
local _M = {}
|
local _M = {}
|
||||||
local balancers = {}
|
local balancers = {}
|
||||||
|
local backends_with_external_name = {}
|
||||||
|
local backends_last_synced_at = 0
|
||||||
|
|
||||||
local function get_implementation(backend)
|
local function get_implementation(backend)
|
||||||
local name = backend["load-balance"] or DEFAULT_LB_ALG
|
local name = backend["load-balance"] or DEFAULT_LB_ALG
|
||||||
|
@ -65,6 +68,12 @@ local function format_ipv6_endpoints(endpoints)
|
||||||
return formatted_endpoints
|
return formatted_endpoints
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function is_backend_with_external_name(backend)
|
||||||
|
local serv_type = backend.service and backend.service.spec
|
||||||
|
and backend.service.spec["type"]
|
||||||
|
return serv_type == "ExternalName"
|
||||||
|
end
|
||||||
|
|
||||||
local function sync_backend(backend)
|
local function sync_backend(backend)
|
||||||
if not backend.endpoints or #backend.endpoints == 0 then
|
if not backend.endpoints or #backend.endpoints == 0 then
|
||||||
return
|
return
|
||||||
|
@ -89,9 +98,7 @@ local function sync_backend(backend)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local service_type = backend.service and backend.service.spec and
|
if is_backend_with_external_name(backend) then
|
||||||
backend.service.spec["type"]
|
|
||||||
if service_type == "ExternalName" then
|
|
||||||
backend = resolve_external_names(backend)
|
backend = resolve_external_names(backend)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -101,6 +108,17 @@ local function sync_backend(backend)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sync_backends()
|
local function sync_backends()
|
||||||
|
local raw_backends_last_synced_at = configuration.get_raw_backends_last_synced_at()
|
||||||
|
ngx.update_time()
|
||||||
|
local current_timestamp = ngx.time()
|
||||||
|
if current_timestamp - backends_last_synced_at < BACKENDS_FORCE_SYNC_INTERVAL
|
||||||
|
and raw_backends_last_synced_at <= backends_last_synced_at then
|
||||||
|
for _, backend_with_external_name in pairs(backends_with_external_name) do
|
||||||
|
sync_backend(backend_with_external_name)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local backends_data = configuration.get_backends_data()
|
local backends_data = configuration.get_backends_data()
|
||||||
if not backends_data then
|
if not backends_data then
|
||||||
balancers = {}
|
balancers = {}
|
||||||
|
@ -117,13 +135,19 @@ local function sync_backends()
|
||||||
for _, new_backend in ipairs(new_backends) do
|
for _, new_backend in ipairs(new_backends) do
|
||||||
sync_backend(new_backend)
|
sync_backend(new_backend)
|
||||||
balancers_to_keep[new_backend.name] = balancers[new_backend.name]
|
balancers_to_keep[new_backend.name] = balancers[new_backend.name]
|
||||||
|
if is_backend_with_external_name(new_backend) then
|
||||||
|
local backend_with_external_name = util.deepcopy(new_backend)
|
||||||
|
backends_with_external_name[backend_with_external_name.name] = backend_with_external_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for backend_name, _ in pairs(balancers) do
|
for backend_name, _ in pairs(balancers) do
|
||||||
if not balancers_to_keep[backend_name] then
|
if not balancers_to_keep[backend_name] then
|
||||||
balancers[backend_name] = nil
|
balancers[backend_name] = nil
|
||||||
|
backends_with_external_name[backend_name] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
backends_last_synced_at = raw_backends_last_synced_at
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_balancer()
|
local function get_balancer()
|
||||||
|
|
|
@ -9,6 +9,14 @@ function _M.get_backends_data()
|
||||||
return tcp_udp_configuration_data:get("backends")
|
return tcp_udp_configuration_data:get("backends")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _M.get_raw_backends_last_synced_at()
|
||||||
|
local raw_backends_last_synced_at = tcp_udp_configuration_data:get("raw_backends_last_synced_at")
|
||||||
|
if raw_backends_last_synced_at == nil then
|
||||||
|
raw_backends_last_synced_at = 1
|
||||||
|
end
|
||||||
|
return raw_backends_last_synced_at
|
||||||
|
end
|
||||||
|
|
||||||
function _M.call()
|
function _M.call()
|
||||||
local sock, err = ngx.req.socket(true)
|
local sock, err = ngx.req.socket(true)
|
||||||
if not sock then
|
if not sock then
|
||||||
|
@ -35,6 +43,17 @@ function _M.call()
|
||||||
ngx.say("error: ", err_conf)
|
ngx.say("error: ", err_conf)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ngx.update_time()
|
||||||
|
local raw_backends_last_synced_at = ngx.time()
|
||||||
|
success, err = tcp_udp_configuration_data:set("raw_backends_last_synced_at",
|
||||||
|
raw_backends_last_synced_at)
|
||||||
|
if not success then
|
||||||
|
ngx.log(ngx.ERR, "dynamic-configuration: error updating when backends sync, " ..
|
||||||
|
"new upstream peers waiting for force syncing: " .. tostring(err))
|
||||||
|
ngx.status = ngx.HTTP_BAD_REQUEST
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return _M
|
return _M
|
||||||
|
|
Loading…
Reference in a new issue