lua-resty-upstream-healthcheck icon indicating copy to clipboard operation
lua-resty-upstream-healthcheck copied to clipboard

Feature request: support dynamic upstream

Open timebug opened this issue 5 years ago • 2 comments
trafficstars

Hi,

The current usage scenario assumes that the upstream configuration will not change dynamically, we only can change upstream configuration via reload nginx.

In some scenarios (see also https://github.com/openresty/lua-resty-upstream-healthcheck/issues/55), we want to dynamically modify the upstream configuration without reload nginx, and the current design cannot satisfy it, so can we add a parameter to hc.spawn_checker to support dynamic upstream mode?

case1: support upstream modify only

  • Module: https://github.com/openresty/lua-upstream-nginx-module (TODO)
  • Module: https://github.com/weibocom/nginx-upsync-module
  • NGINX Plus: https://docs.nginx.com/nginx/admin-guide/load-balancer/dynamic-configuration-api/

In this case, just add a parameter to hc.spawn_checker:

init_worker_by_lua_block {
    local us, err = get_upstreams()
    if not us then
        return
    end

    for _, u in ipairs(us) do
        local ok, err = hc.spawn_checker{
            shm = "healthcheck",
            type = "http",
            upstream = u,

            dynamic = true, -- enable dynamic upstream mode
        }
    end
}

case2: support upstream add/delete/modify

  • Module: https://github.com/yzprofile/ngx_http_dyups_module
  • Tengine: https://tengine.taobao.org/document/http_dyups.html

In this case, we should add a timer to watch global upstream configuration:

init_worker_by_lua_block {
    require "resty.core"

    local upstream = require "ngx.upstream"
    local hc = require "resty.upstream.healthcheck"

    local get_upstreams = upstream.get_upstreams

    local watch
    watch = function (premature)
        if premature then
            return
        end

        local us, err = get_upstreams()
        if not us then
            return
        end

        for _, u in ipairs(us) do
            local ok, err = hc.spawn_checker{
                shm = "healthcheck",
                type = "http",
                upstream = u,

                dynamic = true, -- enable dynamic upstream mode
            }
        end

        local ok, err = ngx.timer.at(2, watch)
    end

    local ok, err = ngx.timer.at(2, watch) -- create a timer to watch global upstream configuration every 2s.
}

Dynamic upstream mode checker behave as follows:

  • When call spawn_checker, if the upstream not exists, new checker will be created, otherwise ignore. (case1)
  • Any time, when delete an upstream, the checker will exit automatically. (case 1)
  • Any time, when modify an upstream (compared with peers md5 digest), the checker will update peers automatically. (case1 + case2)

timebug avatar Oct 10 '20 13:10 timebug

cc @agentzh @spacewander If you are interested in this, I can submit a PR.

timebug avatar Oct 10 '20 13:10 timebug

I have the same requirements. Can you send the modified healthcheck? @timebug

kys1230 avatar Apr 12 '22 08:04 kys1230