Skip to content

Commit

Permalink
bugfix: updated the dns parse result by TTL. (apache#1077)
Browse files Browse the repository at this point in the history
  • Loading branch information
membphis authored and qiujiayu committed Feb 20, 2020
1 parent cb2c611 commit 5237c7b
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 18 deletions.
2 changes: 1 addition & 1 deletion bin/apisix
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,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;
Expand Down
1 change: 1 addition & 0 deletions conf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
59 changes: 45 additions & 14 deletions lua/apisix.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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


Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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


Expand Down
4 changes: 3 additions & 1 deletion lua/apisix/core/lrucache.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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, ...)
Expand All @@ -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)
Expand Down
14 changes: 12 additions & 2 deletions lua/apisix/core/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
37 changes: 37 additions & 0 deletions t/core/lrucache.t
Original file line number Diff line number Diff line change
Expand Up @@ -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]

0 comments on commit 5237c7b

Please sign in to comment.