Skip to content

Instantly share code, notes, and snippets.

@chobits
Last active August 14, 2024 07:35
Show Gist options
  • Save chobits/d21f21d83ca24076377ff31db7ab42c1 to your computer and use it in GitHub Desktop.
Save chobits/d21f21d83ca24076377ff31db7ab42c1 to your computer and use it in GitHub Desktop.
perfermance test for kong old and new dns client library
--[[
run it by this command:
$ resty --shdict "kong_dns_cache 10m" ./perf.lua
]]
setmetatable(_G, nil) -- disable the _G write guard alert log introduced in OpenResty 1.15.8.1
pcall(require, "luarocks.loader")
require("kong.globalpatches")()
local json = require("cjson").encode
local not_found_answers = { errcode = 3, errstr = "not found" }
local a_answers = {{ address = "127.0.0.1", class = 1, ttl = 300, type = 1 }}
-- inject r.query
local resolver = require("resty.dns.resolver")
local query_func = function(self, original_query_func, name, options)
return original_query_func(self, name, options)
end
local old_new = resolver.new
resolver.new = function(...)
local r, err = old_new(...)
if not r then
return nil, err
end
local original_query_func = r.query
r.query = function(self, ...)
return query_func(self, original_query_func, ...)
end
return r
end
resolver.tag = "modified"
--- end of inject r.query
-- restore its API overlapped by the compatible layer
package.loaded["kong.resty.dns_client"] = nil
local client = require("kong.dns.client")
client.resolve = client._resolve
_G.busted_legacy_dns_client = true
package.loaded["kong.resty.dns.client"] = nil
local dns_client = require("kong.resty.dns.client")
--- TEST APIs
local n
local t
local function measure_function_time(f)
t = os.clock()
f()
local delta = os.clock() - t
print(string.format(" run resolve() %d times: %.4f s; avg: %.6f ms per calls",
n, delta, delta/n *1000))
return delta
end
local function test(name, f)
local new_delta, old_delta
print(name)
-- new
local cli = assert(client.new({ family = { "SRV", "A" }, }))
print("+ NEW DNS client")
local new_delta = measure_function_time(function ()
f(function (host) return cli:resolve(host, nil, nil, {}) end)
end)
-- print("+ stats: ", json(cli.stats))
-- old
assert(dns_client.init({ order = { "LAST", "SRV", "A", "CNAME" }, }))
print("+ OLD DNS client")
local old_delta = measure_function_time(function ()
f(function (host) return dns_client.resolve(host, nil, nil, {}, nil) end)
end)
-- last
local improved = (1/(new_delta/n))/(1/(old_delta/n)) - 1
print(("+ Improved: %.2f%%\n"):format(improved * 100))
end
--- run test
print("\n--- runing perf test ---\n")
--- 100% Hit
n = 10000000
local title = "+ 100% hit (miss the first time)"
test(title, function (cli_resolve)
local answers, err, tries
-- skip first miss --
answers, err, tries = cli_resolve("www.konghq.com")
assert(not err, "err:".. tostring(err) .. " tries:" .. json(tries))
t = os.clock()
-- run HIT query
for i = 1, n do
answers, err, tries = cli_resolve("www.konghq.com")
end
assert(not err)
assert(answers[1].name == "www.konghq.com")
end)
--- 0% Hit
n = 100000
local title = "+ 0% Hit (Every query to the nameserver succeeds.)"
local count = 0
query_func = function(self, original_query_func, name, options)
count = count + 1
if options.qtype == 33 then -- SRV
return not_found_answers
end
a_answers[1].name = name
return a_answers
end
test(title, function (cli_resolve)
local answers, err, tries
count = 0
for i = 1, n do
answers, err, tries = cli_resolve(i .. ".konghq.com")
end
assert(answers[1].name == n .. ".konghq.com")
assert(count == n or count == n*2)
end)
@chobits
Copy link
Author

chobits commented Aug 14, 2024

how to test: link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment