You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by we...@apache.org on 2020/02/19 12:30:43 UTC
[incubator-apisix] branch master updated: bugfix: updated the dns
parse result by TTL. (#1077)
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 <me...@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]