ingress-nginx-helm/rootfs/etc/nginx/lua/affinity/balanced.lua

57 lines
1.7 KiB
Lua

-- An affinity mode which makes sure connections are rebalanced when a deployment is scaled.
-- The advantage of this mode is that the load on the pods will be redistributed.
-- The drawback of this mode is that, when scaling up a deployment, roughly (n-c)/n users
-- will lose their session, where c is the current number of pods and n is the new number of
-- pods.
--
-- This class extends/implements the abstract class balancer.sticky.
--
local math = require("math")
local resty_chash = require("resty.chash")
local util = require("util")
local _M = {}
-- Consider the situation of N upstreams one of which is failing.
-- Then the probability to obtain failing upstream after M iterations would be close to (1/N)**M.
-- For the worst case (2 upstreams; 20 iterations) it would be ~10**(-6)
-- which is much better then ~10**(-3) for 10 iterations.
local MAX_UPSTREAM_CHECKS_COUNT = 20
local function get_routing_key(self)
return self:get_cookie(), nil
end
local function set_routing_key(self, key)
self:set_cookie(key)
end
local function pick_new_upstream(self, failed_upstreams)
for i = 1, MAX_UPSTREAM_CHECKS_COUNT do
local key = string.format("%s.%s.%s", ngx.now() + i, ngx.worker.pid(), math.random(999999))
local new_upstream = self.instance:find(key)
if not failed_upstreams[new_upstream] then
return new_upstream, key
end
end
return nil, nil
end
function _M.new(self, sticky_balancer, backend)
local o = sticky_balancer or {}
local nodes = util.get_nodes(backend.endpoints)
-- override sticky.balancer methods
o.instance = resty_chash:new(nodes)
o.get_routing_key = get_routing_key
o.set_routing_key = set_routing_key
o.pick_new_upstream = pick_new_upstream
return sticky_balancer
end
return _M