Last active
August 14, 2024 07:35
-
-
Save chobits/d21f21d83ca24076377ff31db7ab42c1 to your computer and use it in GitHub Desktop.
perfermance test for kong old and new dns client library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --[[ | |
| run it by this command: | |
| $ resty --shdict "kong_dns_cache 10m" --shdict "kong_dns_cache_ipc 10m" ./perf.lua | |
| ]] | |
| pcall(require, "luarocks.loader") | |
| require("kong.globalpatches")() | |
| local _writefile = require("pl.utils").writefile | |
| local tmpname = require("pl.path").tmpname | |
| -- hosted in Route53 in the AWS sandbox | |
| local TEST_DOMAIN = "kong-gateway-testing.link" | |
| local TEST_NS = "198.51.100.0:53" | |
| local TEST_NS = "192.168.5.2:53" -- Kong local official env | |
| local TEST_NS = "192.168.1.1:53" | |
| local TEST_NSS = { TEST_NS } | |
| local not_found_answers = { errcode = 3, errstr = "not found" } | |
| local a_answers = {{ | |
| address = "127.0.0.1", | |
| class = 1, | |
| ttl = 300, | |
| type = 1 | |
| }} | |
| local resolv_path, hosts_path | |
| local function writefile(path, text) | |
| _writefile(path, type(text) == "table" and table.concat(text, "\n") or text) | |
| end | |
| -- create temp resolv.conf and hosts | |
| local resolv_path = tmpname() | |
| local hosts_path = tmpname() | |
| ngx.log(ngx.DEBUG, "create temp resolv.conf:", resolv_path, " hosts:", hosts_path) | |
| -- inject r.query | |
| package.loaded["resty.dns.resolver"] = nil | |
| local resolver = require("resty.dns.resolver") | |
| -- replace this `query_func` upvalue to spy on resolver query calls. | |
| 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 | |
| -- restore its API overlapped by the compatible layer | |
| package.loaded["kong.resty.dns_client"] = nil | |
| local client = require("kong.resty.dns_client") | |
| client.resolve = client._resolve | |
| package.loaded["kong.resty.dns.client"] = nil | |
| local old_client = require("kong.resty.dns.client") | |
| --- TEST apis | |
| local t | |
| local function client_new(opts) | |
| opts = opts or {} | |
| opts.resolv_conf = resolv_path | |
| opts.hosts = hosts_path | |
| return client.new(opts) | |
| end | |
| local n | |
| local new_delta | |
| local old_delta | |
| local function test_new(name, f) | |
| print("[New DNS client]", name) | |
| writefile(resolv_path, { | |
| "nameserver " .. TEST_NS | |
| }) | |
| local cli = assert(client_new({ order = { "LAST", "SRV", "A", "AAAA", "CNAME" } })) | |
| t = os.clock() | |
| f(cli) | |
| new_delta = os.clock() - t | |
| print("It consumes: ", new_delta, "s") | |
| end | |
| local function test_old(name, f) | |
| print("[Old DNS client]", name) | |
| assert(old_client.init({ | |
| resolvConf = { "nameserver " .. TEST_NS, | |
| order = { "LAST", "SRV", "A", "CNAME" } | |
| }})) | |
| local t = os.clock() | |
| f() | |
| old_delta = os.clock() - t | |
| print("It consumes: ", old_delta, "s") | |
| local improved = (n/new_delta)/(n/old_delta) - 1 | |
| print(("Improved: %.2f%%\n"):format(improved * 100)) | |
| end | |
| --- run test | |
| print("\n\n\n\n\n--- runing perf test ---\n") | |
| -------------------- | |
| n = 1000000 | |
| local title = "+ REAL SENARIO: miss the first time, hit 99%" | |
| test_new(title, function (cli) | |
| local answers, err, tries | |
| answers, err, tries = cli:resolve("www.konghq.com") | |
| t = os.clock() -- skip first miss | |
| for i = 1, n do | |
| answers, err, tries = cli:resolve("www.konghq.com") | |
| end | |
| assert(answers[1].name == "www.konghq.com") | |
| end) | |
| test_old(title, function () | |
| local answers, err, tries | |
| answers, err, tries = old_client.resolve("www.konghq.com") | |
| t = os.clock() -- skip first miss | |
| for i = 1, n do | |
| answers, err, tries = old_client.resolve("www.konghq.com") | |
| end | |
| assert(answers[1].name == "www.konghq.com") | |
| end) | |
| test_new(title .. " qtype=A", function (cli) | |
| local answers, err, tries | |
| answers, err, tries = cli:resolve("www.konghq.com", {qtype=1}) | |
| t = os.clock() -- skip first miss | |
| for i = 1, n do | |
| answers, err, tries = cli:resolve("www.konghq.com", {qtype=1}) | |
| end | |
| assert(answers[1].name == "www.konghq.com") | |
| end) | |
| test_old(title .. "qtype=A", function () | |
| local answers, err, tries | |
| answers, err, tries = old_client.resolve("www.konghq.com", {qtype=1}) | |
| t = os.clock() -- skip first miss | |
| for i = 1, n do | |
| answers, err, tries = old_client.resolve("www.konghq.com", {qtype=1}) | |
| end | |
| assert(answers[1].name == "www.konghq.com") | |
| end) | |
| -------------------- | |
| n = 10000 | |
| local title = "+ 100% miss, query suceeds (subtracting network I/O time.)" | |
| local count = 0 | |
| query_func = function(self, original_query_func, name, options) | |
| count = count + 1 | |
| if options.qtype == 33 then | |
| return not_found_answers | |
| end | |
| a_answers[1].name = name | |
| return a_answers | |
| end | |
| test_new(title, function (cli) | |
| 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 == 2 * n) | |
| end) | |
| test_old(title, function () | |
| local answers, err, tries | |
| count = 0 | |
| for i = 1, n do | |
| answers, err, tries = old_client.resolve(i .. ".konghq.com") | |
| end | |
| assert(answers[1].name == n .. ".konghq.com") | |
| assert(count == 2 * n) | |
| end) | |
| test_new(title .. " qtype=A", function (cli) | |
| local answers, err, tries | |
| count = 0 | |
| for i = 1, n do | |
| answers, err, tries = cli:resolve(i .. ".konghq.com", {qtype=1}) | |
| end | |
| assert(answers[1].name == n .. ".konghq.com") | |
| assert(count == n) | |
| end) | |
| test_old(title .. " qtype=A", function () | |
| local answers, err, tries | |
| count = 0 | |
| for i = 1, n do | |
| answers, err, tries = old_client.resolve(i .. ".konghq.com", {qtype =1}) | |
| end | |
| assert(answers[1].name == n .. ".konghq.com") | |
| assert(count == n) | |
| end) | |
| -------------------- | |
| n = 10000 | |
| local title = "+ 100% miss, query gets empty record (subtracting network I/O time)." | |
| local count = 0 | |
| query_func = function(self, original_query_func, name, options) | |
| -- print(" query: ", name .. options.qtype) | |
| count = count + 1 | |
| return not_found_answers | |
| end | |
| test_new(title, function (cli) | |
| local answers, err, tries | |
| count = 0 | |
| for i = 1, n do | |
| answers, err, tries = cli:resolve(i .. ".konghq.com") | |
| end | |
| assert(not answers) | |
| assert(count == 4 * n) | |
| end) | |
| test_old(title, function () | |
| local answers, err, tries | |
| count = 0 | |
| for i = 1, n do | |
| answers, err, tries = old_client.resolve(i .. ".konghq.com") | |
| end | |
| --assert(not answers) | |
| assert(count == 4 * n) | |
| end) | |
| test_new(title .. " qtype=A", function (cli) | |
| local answers, err, tries | |
| count = 0 | |
| for i = 1, n do | |
| answers, err, tries = cli:resolve(i .. ".konghq.com", {qtype=1}) | |
| end | |
| assert(not answers) | |
| assert(count == n) | |
| end) | |
| test_old(title .. " qtype=A", function () | |
| local answers, err, tries | |
| count = 0 | |
| for i = 1, n do | |
| answers, err, tries = old_client.resolve(i .. ".konghq.com", {qtype=1}) | |
| end | |
| --assert(not answers) | |
| assert(count == n) | |
| end) | |
| --- end | |
| if resolv_path then | |
| os.remove(resolv_path) | |
| end | |
| if hosts_path then | |
| os.remove(hosts_path) | |
| end |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how to test: link