This is an automated email from the ASF dual-hosted git repository. membphis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push: new 4cf30bf refactor: keep health checker with the upstream's parent (#3325) 4cf30bf is described below commit 4cf30bf2ac79d766355b89067e5e728bb02f232f Author: 罗泽轩 <spacewander...@gmail.com> AuthorDate: Mon Jan 18 08:21:39 2021 -0600 refactor: keep health checker with the upstream's parent (#3325) A upstream's parent can only have one running checker. Previously, when a checker is evicted by lrucache, it is still running. Now health checker & upstream in used is 1:1. --- apisix/core.lua | 39 ++++++++++++++++++----------------- apisix/core/config_util.lua | 23 +++++++++++++++++++++ apisix/upstream.lua | 46 ++++++++++++++++++++++++------------------ t/node/healthcheck-discovery.t | 5 +++-- 4 files changed, 72 insertions(+), 41 deletions(-) diff --git a/apisix/core.lua b/apisix/core.lua index f9432e0..f994de9 100644 --- a/apisix/core.lua +++ b/apisix/core.lua @@ -29,23 +29,24 @@ config.type = config_center return { - version = require("apisix.core.version"), - log = log, - config = config, - sleep = utils.sleep, - json = require("apisix.core.json"), - table = require("apisix.core.table"), - request = require("apisix.core.request"), - response = require("apisix.core.response"), - lrucache = require("apisix.core.lrucache"), - schema = require("apisix.schema_def"), - string = require("apisix.core.string"), - ctx = require("apisix.core.ctx"), - timer = require("apisix.core.timer"), - id = require("apisix.core.id"), - utils = utils, - etcd = require("apisix.core.etcd"), - http = require("apisix.core.http"), - tablepool= require("tablepool"), - empty_tab= {}, + version = require("apisix.core.version"), + log = log, + config = config, + config_util = require("apisix.core.config_util"), + sleep = utils.sleep, + json = require("apisix.core.json"), + table = require("apisix.core.table"), + request = require("apisix.core.request"), + response = require("apisix.core.response"), + lrucache = require("apisix.core.lrucache"), + schema = require("apisix.schema_def"), + string = require("apisix.core.string"), + ctx = require("apisix.core.ctx"), + timer = require("apisix.core.timer"), + id = require("apisix.core.id"), + utils = utils, + etcd = require("apisix.core.etcd"), + http = require("apisix.core.http"), + tablepool = require("tablepool"), + empty_tab = {}, } diff --git a/apisix/core/config_util.lua b/apisix/core/config_util.lua index 1e39921..cc29ea4 100644 --- a/apisix/core/config_util.lua +++ b/apisix/core/config_util.lua @@ -14,6 +14,7 @@ -- See the License for the specific language governing permissions and -- limitations under the License. -- +local core_tab = require("apisix.core.table") local setmetatable = setmetatable local type = type @@ -42,4 +43,26 @@ function _M.iterate_values(tab) end +-- Add a clean handler to a runtime configuration item. +-- The clean handler will be called when the item is deleted from configuration +-- or cancelled. Note that Nginx worker exit doesn't trigger the clean handler. +-- Retuen an index so that we can cancel it later. +function _M.add_clean_handler(item, func) + local idx = #item.clean_handlers + 1 + item.clean_handlers[idx] = func + return idx +end + + +-- cancel a clean handler added by add_clean_handler. +-- If `fire` is true, call the clean handler. +function _M.cancel_clean_handler(item, idx, fire) + local f = item.clean_handlers[idx] + core_tab.remove(item.clean_handlers, idx) + if fire then + f(item) + end +end + + return _M diff --git a/apisix/upstream.lua b/apisix/upstream.lua index ecd99bf..da19e45 100644 --- a/apisix/upstream.lua +++ b/apisix/upstream.lua @@ -26,11 +26,6 @@ local upstreams local healthcheck -local lrucache_checker = core.lrucache.new({ - ttl = 300, count = 256 -}) - - local _M = {} @@ -57,12 +52,24 @@ end _M.set = set_directly +local function release_checker(healthcheck_parent) + local checker = healthcheck_parent.checker + core.log.info("try to release checker: ", tostring(checker)) + checker:clear() + checker:stop() +end + + local function create_checker(upstream) if healthcheck == nil then healthcheck = require("resty.healthcheck") end local healthcheck_parent = upstream.parent + if healthcheck_parent.checker and healthcheck_parent.checker_upstream == upstream then + return healthcheck_parent.checker + end + local checker, err = healthcheck.new({ name = "upstream#" .. healthcheck_parent.key, shm_name = "upstream-healthcheck", @@ -84,29 +91,28 @@ local function create_checker(upstream) end end - core.table.insert(healthcheck_parent.clean_handlers, function () - core.log.info("try to release checker: ", tostring(checker)) - checker:clear() - checker:stop() - end) + if healthcheck_parent.checker then + core.config_util.cancel_clean_handler(healthcheck_parent, + healthcheck_parent.checker_idx, true) + end core.log.info("create new checker: ", tostring(checker)) + + healthcheck_parent.checker = checker + healthcheck_parent.checker_upstream = upstream + healthcheck_parent.checker_idx = + core.config_util.add_clean_handler(healthcheck_parent, release_checker) + return checker end -local function fetch_healthchecker(upstream, version) +local function fetch_healthchecker(upstream) if not upstream.checks then - return - end - - if upstream.checker then - return + return nil end - local checker = lrucache_checker(upstream, version, - create_checker, upstream) - return checker + return create_checker(upstream) end @@ -164,7 +170,7 @@ function _M.set_by_route(route, api_ctx) end if nodes_count > 1 then - local checker = fetch_healthchecker(up_conf, api_ctx.upstream_version) + local checker = fetch_healthchecker(up_conf) api_ctx.up_checker = checker end diff --git a/t/node/healthcheck-discovery.t b/t/node/healthcheck-discovery.t index 6123fff..41c490e 100644 --- a/t/node/healthcheck-discovery.t +++ b/t/node/healthcheck-discovery.t @@ -151,9 +151,10 @@ routes: } } --- grep_error_log eval -qr/create new checker: table/ +qr/(create new checker|try to release checker): table/ --- grep_error_log_out create new checker: table +try to release checker: table create new checker: table @@ -198,6 +199,6 @@ routes: } } --- grep_error_log eval -qr/create new checker: table/ +qr/(create new checker|try to release checker): table/ --- grep_error_log_out create new checker: table