This is an automated email from the ASF dual-hosted git repository. wenming pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-apisix.git
The following commit(s) were added to refs/heads/master by this push: new de16a7e bugfix: updated the dns parse result by TTL. (#1077) de16a7e is described below commit de16a7e04f6d316a05743666261f159508355416 Author: YuanSheng Wang <membp...@gmail.com> AuthorDate: Wed Feb 19 20:30:34 2020 +0800 bugfix: updated the dns parse result by TTL. (#1077) --- bin/apisix | 2 +- conf/config.yaml | 1 + lua/apisix.lua | 59 +++++++++++++++++++++++++++++++++----------- lua/apisix/core/lrucache.lua | 4 ++- lua/apisix/core/utils.lua | 14 +++++++++-- t/core/lrucache.t | 37 +++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 18 deletions(-) diff --git a/bin/apisix b/bin/apisix index 7e4b89a..5e68c3f 100755 --- a/bin/apisix +++ b/bin/apisix @@ -183,7 +183,7 @@ http { lua_socket_log_errors off; - resolver {% for _, dns_addr in ipairs(dns_resolver or {}) do %} {*dns_addr*} {% end %} ipv6=off; + resolver {% for _, dns_addr in ipairs(dns_resolver or {}) do %} {*dns_addr*} {% end %} valid={*dns_resolver_valid*} ipv6=off; resolver_timeout 5; lua_http10_buffering off; diff --git a/conf/config.yaml b/conf/config.yaml index 9e098d9..3281f47 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -55,6 +55,7 @@ apisix: - 223.5.5.5 - 1.1.1.1 - 8.8.8.8 + dns_resolver_valid: 30 # valid time for dns result 30 seconds ssl: enable: true diff --git a/lua/apisix.lua b/lua/apisix.lua index bee4376..7517c46 100644 --- a/lua/apisix.lua +++ b/lua/apisix.lua @@ -33,9 +33,7 @@ local tostring = tostring local load_balancer -local parsed_domain = core.lrucache.new({ - ttl = 300, count = 512 -}) +local parsed_domain local _M = {version = 0.3} @@ -85,6 +83,14 @@ function _M.http_init_worker() end require("apisix.debug").init_worker() + + local local_conf = core.config.local_conf() + local dns_resolver_valid = local_conf and local_conf.apisix and + local_conf.apisix.dns_resolver_valid + + parsed_domain = core.lrucache.new({ + ttl = dns_resolver_valid, count = 512, invalid_stale = true, + }) end @@ -174,14 +180,20 @@ local function parse_domain_in_up(up, ver) local host, port = core.utils.parse_addr(addr) if not ipmatcher.parse_ipv4(host) and not ipmatcher.parse_ipv6(host) then - local ip_info = core.utils.dns_parse(dns_resolver, host) - core.log.info("parse addr: ", core.json.delay_encode(ip_info), - " resolver: ", core.json.delay_encode(dns_resolver), - " addr: ", addr) - if ip_info and ip_info.address then + local ip_info, err = core.utils.dns_parse(dns_resolver, host) + if not ip_info then + return nil, err + end + + core.log.info("parse addr: ", core.json.delay_encode(ip_info)) + core.log.info("resolver: ", core.json.delay_encode(dns_resolver)) + core.log.info("host: ", host) + if ip_info.address then new_nodes[ip_info.address .. ":" .. port] = weight core.log.info("dns resolver domain: ", host, " to ", ip_info.address) + else + return nil, "failed to parse domain in route" end else new_nodes[addr] = weight @@ -206,15 +218,22 @@ local function parse_domain_in_route(route, ver) local host, port = core.utils.parse_addr(addr) if not ipmatcher.parse_ipv4(host) and not ipmatcher.parse_ipv6(host) then - local ip_info = core.utils.dns_parse(dns_resolver, host) - core.log.info("parse addr: ", core.json.delay_encode(ip_info), - " resolver: ", core.json.delay_encode(dns_resolver), - " addr: ", addr) + local ip_info, err = core.utils.dns_parse(dns_resolver, host) + if not ip_info then + return nil, err + end + + core.log.info("parse addr: ", core.json.delay_encode(ip_info)) + core.log.info("resolver: ", core.json.delay_encode(dns_resolver)) + core.log.info("host: ", host) if ip_info and ip_info.address then new_nodes[ip_info.address .. ":" .. port] = weight core.log.info("dns resolver domain: ", host, " to ", ip_info.address) + else + return nil, "failed to parse domain in route" end + else new_nodes[addr] = weight end @@ -312,8 +331,12 @@ function _M.http_access_phase() if upstreams_etcd then local upstream = upstreams_etcd:get(tostring(up_id)) if upstream.has_domain then - parsed_domain(upstream, api_ctx.conf_version, - parse_domain_in_up, upstream) + local _, err = parsed_domain(upstream, api_ctx.conf_version, + parse_domain_in_up, upstream) + if err then + core.log.error("failed to parse domain in upstream: ", err) + return core.response.exit(500) + end end if upstream.value.enable_websocket then @@ -520,6 +543,14 @@ function _M.stream_init_worker() plugin.init_worker() load_balancer = require("apisix.balancer").run + + local local_conf = core.config.local_conf() + local dns_resolver_valid = local_conf and local_conf.apisix and + local_conf.apisix.dns_resolver_valid + + parsed_domain = core.lrucache.new({ + ttl = dns_resolver_valid, count = 512, invalid_stale = true, + }) end diff --git a/lua/apisix/core/lrucache.lua b/lua/apisix/core/lrucache.lua index 6804673..aee4697 100644 --- a/lua/apisix/core/lrucache.lua +++ b/lua/apisix/core/lrucache.lua @@ -32,6 +32,7 @@ local function new_lru_fun(opts) local item_count = opts and opts.count or GLOBAL_ITEMS_COUNT local item_ttl = opts and opts.ttl or GLOBAL_TTL local item_release = opts and opts.release + local invalid_stale = opts and opts.invalid_stale local lru_obj = lru_new(item_count) return function (key, version, create_obj_fun, ...) @@ -45,7 +46,8 @@ local function new_lru_fun(opts) return obj.val end - if stale_obj and stale_obj._cache_ver == version then + if not invalid_stale and stale_obj and + stale_obj._cache_ver == version then lru_obj:set(key, stale_obj, item_ttl) local met_tab = getmetatable(stale_obj) diff --git a/lua/apisix/core/utils.lua b/lua/apisix/core/utils.lua index 44a380c..98e678e 100644 --- a/lua/apisix/core/utils.lua +++ b/lua/apisix/core/utils.lua @@ -57,7 +57,7 @@ function _M.split_uri(uri) end -function _M.dns_parse(resolvers, domain) +local function dns_parse(resolvers, domain) local r, err = resolver:new{ nameservers = table.clone(resolvers), retrans = 5, -- 5 retransmissions on receive timeout @@ -79,8 +79,18 @@ function _M.dns_parse(resolvers, domain) end local idx = math.random(1, #answers) - return answers[idx] + local answer = answers[idx] + if answer.type == 1 then + return answer + end + + if answer.type ~= 5 then + return nil, "unsupport DNS answer" + end + + return dns_parse(resolvers, answer.cname) end +_M.dns_parse = dns_parse local function rfind_char(s, ch, idx) diff --git a/t/core/lrucache.t b/t/core/lrucache.t index bd5a32e..bfb18ee 100644 --- a/t/core/lrucache.t +++ b/t/core/lrucache.t @@ -204,3 +204,40 @@ release: {"_cache_ver":"t1","name":"aaa"} obj: {"_cache_ver":"t2","name":"bbb"} --- no_error_log [error] + + + +=== TEST 6: invalid_stale = true +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + + local idx = 0 + local function create_obj() + idx = idx + 1 + return {idx = idx} + end + + local lru_get = core.lrucache.new({ + ttl = 0.1, count = 256, invalid_stale = true, + }) + + local obj = lru_get("key", "ver", create_obj) + ngx.say("obj: ", core.json.encode(obj)) + local obj = lru_get("key", "ver", create_obj) + ngx.say("obj: ", core.json.encode(obj)) + + ngx.sleep(0.15) + local obj = lru_get("key", "ver", create_obj) + ngx.say("obj: ", core.json.encode(obj)) + } + } +--- request +GET /t +--- response_body +obj: {"idx":1,"_cache_ver":"ver"} +obj: {"idx":1,"_cache_ver":"ver"} +obj: {"idx":2,"_cache_ver":"ver"} +--- no_error_log +[error]