merge from master
This commit is contained in:
commit
ce6e564f82
86 changed files with 1448 additions and 3530 deletions
|
|
@ -5,38 +5,17 @@
|
|||
-- /finagle-core/src/main/scala/com/twitter/finagle/loadbalancer/PeakEwma.scala
|
||||
|
||||
|
||||
local resty_lock = require("resty.lock")
|
||||
local util = require("util")
|
||||
local split = require("util.split")
|
||||
|
||||
local DECAY_TIME = 10 -- this value is in seconds
|
||||
local LOCK_KEY = ":ewma_key"
|
||||
local PICK_SET_SIZE = 2
|
||||
|
||||
local ewma_lock = resty_lock:new("locks", {timeout = 0, exptime = 0.1})
|
||||
local balancer_ewma = {}
|
||||
local balancer_ewma_last_touched_at = {}
|
||||
|
||||
local _M = { name = "ewma" }
|
||||
|
||||
local function lock(upstream)
|
||||
local _, err = ewma_lock:lock(upstream .. LOCK_KEY)
|
||||
if err then
|
||||
if err ~= "timeout" then
|
||||
ngx.log(ngx.ERR, string.format("EWMA Balancer failed to lock: %s", tostring(err)))
|
||||
end
|
||||
end
|
||||
|
||||
return err
|
||||
end
|
||||
|
||||
local function unlock()
|
||||
local ok, err = ewma_lock:unlock()
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR, string.format("EWMA Balancer failed to unlock: %s", tostring(err)))
|
||||
end
|
||||
|
||||
return err
|
||||
end
|
||||
|
||||
local function decay_ewma(ewma, last_touched_at, rtt, now)
|
||||
local td = now - last_touched_at
|
||||
td = (td > 0) and td or 0
|
||||
|
|
@ -47,40 +26,18 @@ local function decay_ewma(ewma, last_touched_at, rtt, now)
|
|||
end
|
||||
|
||||
local function get_or_update_ewma(upstream, rtt, update)
|
||||
local lock_err = nil
|
||||
if update then
|
||||
lock_err = lock(upstream)
|
||||
end
|
||||
local ewma = ngx.shared.balancer_ewma:get(upstream) or 0
|
||||
if lock_err ~= nil then
|
||||
return ewma, lock_err
|
||||
end
|
||||
local ewma = balancer_ewma[upstream] or 0
|
||||
|
||||
local now = ngx.now()
|
||||
local last_touched_at = ngx.shared.balancer_ewma_last_touched_at:get(upstream) or 0
|
||||
local last_touched_at = balancer_ewma_last_touched_at[upstream] or 0
|
||||
ewma = decay_ewma(ewma, last_touched_at, rtt, now)
|
||||
|
||||
if not update then
|
||||
return ewma, nil
|
||||
end
|
||||
|
||||
local success, err, forcible = ngx.shared.balancer_ewma_last_touched_at:set(upstream, now)
|
||||
if not success then
|
||||
ngx.log(ngx.WARN, "balancer_ewma_last_touched_at:set failed " .. err)
|
||||
end
|
||||
if forcible then
|
||||
ngx.log(ngx.WARN, "balancer_ewma_last_touched_at:set valid items forcibly overwritten")
|
||||
end
|
||||
|
||||
success, err, forcible = ngx.shared.balancer_ewma:set(upstream, ewma)
|
||||
if not success then
|
||||
ngx.log(ngx.WARN, "balancer_ewma:set failed " .. err)
|
||||
end
|
||||
if forcible then
|
||||
ngx.log(ngx.WARN, "balancer_ewma:set valid items forcibly overwritten")
|
||||
end
|
||||
|
||||
unlock()
|
||||
balancer_ewma_last_touched_at[upstream] = now
|
||||
balancer_ewma[upstream] = ewma
|
||||
return ewma, nil
|
||||
end
|
||||
|
||||
|
|
@ -153,8 +110,8 @@ function _M.sync(self, backend)
|
|||
self.peers = backend.endpoints
|
||||
|
||||
-- TODO: Reset state of EWMA per backend
|
||||
ngx.shared.balancer_ewma:flush_all()
|
||||
ngx.shared.balancer_ewma_last_touched_at:flush_all()
|
||||
balancer_ewma = {}
|
||||
balancer_ewma_last_touched_at = {}
|
||||
end
|
||||
|
||||
function _M.new(self, backend)
|
||||
|
|
|
|||
|
|
@ -94,22 +94,17 @@ local function set_cookie(self, value)
|
|||
end
|
||||
end
|
||||
|
||||
local function pick_random(instance)
|
||||
local index = math.random(instance.npoints)
|
||||
return instance:next(index)
|
||||
end
|
||||
|
||||
function _M.balance(self)
|
||||
local cookie, err = ck:new()
|
||||
if not cookie then
|
||||
ngx.log(ngx.ERR, err)
|
||||
return pick_random(self.instance)
|
||||
ngx.log(ngx.ERR, "error while initializing cookie: " .. tostring(err))
|
||||
return
|
||||
end
|
||||
|
||||
local key = cookie:get(self.cookie_name)
|
||||
if not key then
|
||||
local tmp_endpoint_string = pick_random(self.instance)
|
||||
key = encrypted_endpoint_string(self, tmp_endpoint_string)
|
||||
local random_str = string.format("%s.%s", ngx.now(), ngx.worker.pid())
|
||||
key = encrypted_endpoint_string(self, random_str)
|
||||
set_cookie(self, key)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -26,10 +26,6 @@ describe("Balancer ewma", function()
|
|||
local instance = balancer_ewma:new(backend)
|
||||
|
||||
local stats = { ["10.184.7.40:8080"] = 0.5, ["10.184.97.100:8080"] = 0.3 }
|
||||
ngx.shared.balancer_ewma.get = function(self, key) return stats[key] end
|
||||
local t = ngx.now()-10
|
||||
ngx.shared.balancer_ewma_last_touched_at.get = function(self, key) return t end
|
||||
|
||||
|
||||
local peer = instance:balance()
|
||||
assert.equal("10.184.97.100:8080", peer)
|
||||
|
|
@ -52,13 +48,7 @@ describe("Balancer ewma", function()
|
|||
endpoints = { { address = "10.184.7.40", port = "8080", maxFails = 0, failTimeout = 0 } }
|
||||
}
|
||||
|
||||
local s1 = spy.on(ngx.shared.balancer_ewma, "flush_all")
|
||||
local s2 = spy.on(ngx.shared.balancer_ewma_last_touched_at, "flush_all")
|
||||
|
||||
instance:sync(new_backend)
|
||||
|
||||
assert.spy(s1).was_not_called()
|
||||
assert.spy(s2).was_not_called()
|
||||
end)
|
||||
|
||||
it("updates endpoints", function()
|
||||
|
|
@ -77,13 +67,7 @@ describe("Balancer ewma", function()
|
|||
local new_backend = util.deepcopy(backend)
|
||||
new_backend.endpoints[1].maxFails = 3
|
||||
|
||||
local s1 = spy.on(ngx.shared.balancer_ewma, "flush_all")
|
||||
local s2 = spy.on(ngx.shared.balancer_ewma_last_touched_at, "flush_all")
|
||||
|
||||
instance:sync(new_backend)
|
||||
|
||||
assert.spy(s1).was_called()
|
||||
assert.spy(s2).was_called()
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,8 @@ describe("Sticky", function()
|
|||
local cookie_instance = {
|
||||
set = function(self, payload)
|
||||
assert.equal(payload.key, test_backend.sessionAffinityConfig.cookieSessionAffinity.name)
|
||||
assert.equal(payload.value, util[test_backend_hash_fn .. "_digest"](test_backend_endpoint))
|
||||
local expected_len = #util[test_backend_hash_fn .. "_digest"]("anything")
|
||||
assert.equal(#payload.value, expected_len)
|
||||
assert.equal(payload.path, ngx.var.location_path)
|
||||
assert.equal(payload.domain, nil)
|
||||
assert.equal(payload.httponly, true)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue