From 04527555794bc4aeb4c30e0e6b17f698d8da6c83 Mon Sep 17 00:00:00 2001 From: kingluo Date: Tue, 18 Oct 2022 16:56:23 +0800 Subject: [PATCH 01/11] fix: add dynamic route cache key --- apisix/core/ai.lua | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index 99c38b05bd65..219040023dd9 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -16,8 +16,27 @@ -- local require = require local core = require("apisix.core") +local template = require("resty.template") local ipairs = ipairs +local get_cache_key_func + +local get_cache_key_func_def_render = template.compile([[ +return function(ctx) + local key = ctx.var.uri + + {% if route_flags["methods"] then %} + key = key .. "\0" .. ctx.var.method + {% end %} + + {% if route_flags["host"] then %} + key = key .. "\1" .. ctx.var.host + {% end %} + + return key +end +]]) + local route_lrucache = core.lrucache.new({ -- TODO: we need to set the cache size by count of routes -- if we have done this feature, we need to release the origin lrucache @@ -36,8 +55,7 @@ end local function ai_match(ctx) - -- TODO: we need to generate cache key dynamically - local key = ctx.var.uri .. "-" .. ctx.var.method .. "-" .. ctx.var.host + local key = get_cache_key_func(ctx) local ver = router.user_routes.conf_version local route_cache = route_lrucache(key, ver, match_route, ctx) @@ -52,6 +70,14 @@ function _M.routes_analyze(routes) -- TODO: we need to add a option in config.yaml to enable this feature(default is true) local route_flags = core.table.new(0, 2) for _, route in ipairs(routes) do + if route.methods then + route_flags["methods"] = true + end + + if route.host or route.hosts then + route_flags["host"] = true + end + if route.vars then route_flags["vars"] = true end @@ -71,6 +97,10 @@ function _M.routes_analyze(routes) else core.log.info("use ai plane to match route") router.match = ai_match + local str = get_cache_key_func_def_render({route_flags = route_flags}) + local ok, func = pcall(str) + assert(ok) + get_cache_key_func = func() end end From 3ef764efa975dce7f6d499f5d6320480eae8b7d3 Mon Sep 17 00:00:00 2001 From: kingluo Date: Tue, 18 Oct 2022 17:11:07 +0800 Subject: [PATCH 02/11] fix lint --- apisix/core/ai.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index 219040023dd9..3be7040b2a74 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -18,6 +18,8 @@ local require = require local core = require("apisix.core") local template = require("resty.template") local ipairs = ipairs +local pcall = pcall +local assert = assert local get_cache_key_func From 37899ff0937bd8c5dc2f00a80c574012cbc0f471 Mon Sep 17 00:00:00 2001 From: kingluo Date: Tue, 18 Oct 2022 17:19:05 +0800 Subject: [PATCH 03/11] adjust --- apisix/core/ai.lua | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index 3be7040b2a74..e0e860894f08 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -26,14 +26,12 @@ local get_cache_key_func local get_cache_key_func_def_render = template.compile([[ return function(ctx) local key = ctx.var.uri - - {% if route_flags["methods"] then %} - key = key .. "\0" .. ctx.var.method - {% end %} - - {% if route_flags["host"] then %} - key = key .. "\1" .. ctx.var.host - {% end %} + {% if route_flags["methods"] then %} + .. "\0" .. ctx.var.method + {% end %} + {% if route_flags["host"] then %} + .. "\0" .. ctx.var.host + {% end %} return key end From db0c88400093f87661edc637a056793aaed82d82 Mon Sep 17 00:00:00 2001 From: kingluo Date: Tue, 18 Oct 2022 17:55:16 +0800 Subject: [PATCH 04/11] bugfix --- apisix/core/ai.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index e0e860894f08..03f952b9c534 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -20,6 +20,7 @@ local template = require("resty.template") local ipairs = ipairs local pcall = pcall local assert = assert +local loadstring = loadstring local get_cache_key_func @@ -98,9 +99,10 @@ function _M.routes_analyze(routes) core.log.info("use ai plane to match route") router.match = ai_match local str = get_cache_key_func_def_render({route_flags = route_flags}) - local ok, func = pcall(str) + local func = loadstring(str) + assert(func) + local ok, get_cache_key_func = pcall(func) assert(ok) - get_cache_key_func = func() end end From 203242b6db483c6bd4b0174bff408384e70f7421 Mon Sep 17 00:00:00 2001 From: kingluo Date: Tue, 18 Oct 2022 18:01:48 +0800 Subject: [PATCH 05/11] bugfix --- apisix/core/ai.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index 03f952b9c534..8d32f42ce7cd 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -101,7 +101,8 @@ function _M.routes_analyze(routes) local str = get_cache_key_func_def_render({route_flags = route_flags}) local func = loadstring(str) assert(func) - local ok, get_cache_key_func = pcall(func) + local ok + ok, get_cache_key_func = pcall(func) assert(ok) end end From ea1639791726a711fd8d22f3a77186340291ab68 Mon Sep 17 00:00:00 2001 From: kingluo Date: Tue, 18 Oct 2022 18:30:15 +0800 Subject: [PATCH 06/11] bugfix --- apisix/core/ai.lua | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index 8d32f42ce7cd..76615e43614d 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -16,15 +16,14 @@ -- local require = require local core = require("apisix.core") -local template = require("resty.template") local ipairs = ipairs local pcall = pcall -local assert = assert local loadstring = loadstring local get_cache_key_func +local get_cache_key_func_def_render -local get_cache_key_func_def_render = template.compile([[ +local get_cache_key_func_def = [[ return function(ctx) local key = ctx.var.uri {% if route_flags["methods"] then %} @@ -36,7 +35,7 @@ return function(ctx) return key end -]]) +]] local route_lrucache = core.lrucache.new({ -- TODO: we need to set the cache size by count of routes @@ -98,12 +97,26 @@ function _M.routes_analyze(routes) else core.log.info("use ai plane to match route") router.match = ai_match + + if get_cache_key_func_def_render == nil then + local template = require("resty.template") + get_cache_key_func_def_render = template.compile(get_cache_key_func_def) + end + local str = get_cache_key_func_def_render({route_flags = route_flags}) - local func = loadstring(str) - assert(func) - local ok - ok, get_cache_key_func = pcall(func) - assert(ok) + local func, err = loadstring(str) + if func == nil then + core.log.error("generate get_cache_key_func failed:", err) + router.match = orig_router_match + else + local ok + ok, get_cache_key_func = pcall(func) + if not ok then + local err = get_cache_key_func + core.log.error("generate get_cache_key_func failed:", err) + router.match = orig_router_match + end + end end end From 67a15d75e22b863dbe72bc0b56a45fae492ecf49 Mon Sep 17 00:00:00 2001 From: kingluo Date: Tue, 18 Oct 2022 23:46:42 +0800 Subject: [PATCH 07/11] fix PR --- apisix/core/ai.lua | 44 +++++++----- t/core/ai.t | 174 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+), 19 deletions(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index 76615e43614d..b3496f5657da 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -25,15 +25,13 @@ local get_cache_key_func_def_render local get_cache_key_func_def = [[ return function(ctx) - local key = ctx.var.uri + return ctx.var.uri {% if route_flags["methods"] then %} .. "\0" .. ctx.var.method {% end %} {% if route_flags["host"] then %} .. "\0" .. ctx.var.host {% end %} - - return key end ]] @@ -56,6 +54,7 @@ end local function ai_match(ctx) local key = get_cache_key_func(ctx) + core.log.info("route cache key: ", core.log.delay_exec(ngx.encode_base64, key)) local ver = router.user_routes.conf_version local route_cache = route_lrucache(key, ver, match_route, ctx) @@ -66,6 +65,27 @@ local function ai_match(ctx) end +local function gen_get_cache_key_func(route_flags) + if get_cache_key_func_def_render == nil then + local template = require("resty.template") + get_cache_key_func_def_render = template.compile(get_cache_key_func_def) + end + + local str = get_cache_key_func_def_render({route_flags = route_flags}) + local func, err = loadstring(str) + if func == nil then + return err + else + local ok + ok, get_cache_key_func = pcall(func) + if not ok then + local err = get_cache_key_func + return err + end + end +end + + function _M.routes_analyze(routes) -- TODO: we need to add a option in config.yaml to enable this feature(default is true) local route_flags = core.table.new(0, 2) @@ -98,24 +118,10 @@ function _M.routes_analyze(routes) core.log.info("use ai plane to match route") router.match = ai_match - if get_cache_key_func_def_render == nil then - local template = require("resty.template") - get_cache_key_func_def_render = template.compile(get_cache_key_func_def) - end - - local str = get_cache_key_func_def_render({route_flags = route_flags}) - local func, err = loadstring(str) - if func == nil then + local err = gen_get_cache_key_func(route_flags) + if err then core.log.error("generate get_cache_key_func failed:", err) router.match = orig_router_match - else - local ok - ok, get_cache_key_func = pcall(func) - if not ok then - local err = get_cache_key_func - core.log.error("generate get_cache_key_func failed:", err) - router.match = orig_router_match - end end end end diff --git a/t/core/ai.t b/t/core/ai.t index a54c4ea0bb2b..0f0cb70eb61a 100644 --- a/t/core/ai.t +++ b/t/core/ai.t @@ -474,3 +474,177 @@ qr/use ai plane to match route/ --- grep_error_log_out use ai plane to match route use ai plane to match route + + + +=== TEST 6: route key: uri +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local http = require "resty.http" + local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello" + + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + ngx.sleep(1) + + -- enable + do + local httpc = http.new() + local res, err = httpc:request_uri(uri) + assert(res.status == 200) + if not res then + ngx.log(ngx.ERR, err) + return + end + end + + local httpc = http.new() + local res, err = httpc:request_uri(uri) + assert(res.status == 200) + if not res then + ngx.log(ngx.ERR, err) + return + end + + ngx.say("done") + } + } +--- response_body +done +--- error_log +route cache key: L2hlbGxv + + + +=== TEST 7: route key: uri + method +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local http = require "resty.http" + local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello" + + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "methods": ["GET"], + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + ngx.sleep(1) + + -- enable + do + local httpc = http.new() + local res, err = httpc:request_uri(uri) + assert(res.status == 200) + if not res then + ngx.log(ngx.ERR, err) + return + end + end + + local httpc = http.new() + local res, err = httpc:request_uri(uri) + assert(res.status == 200) + if not res then + ngx.log(ngx.ERR, err) + return + end + + ngx.say("done") + } + } +--- response_body +done +--- error_log +route cache key: L2hlbGxvAEdFVA== + + + +=== TEST 8: route key: uri + method + host +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local http = require "resty.http" + local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello" + + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "host": "127.0.0.1", + "methods": ["GET"], + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + ngx.sleep(1) + + -- enable + do + local httpc = http.new() + local res, err = httpc:request_uri(uri) + assert(res.status == 200) + if not res then + ngx.log(ngx.ERR, err) + return + end + end + + local httpc = http.new() + local res, err = httpc:request_uri(uri) + assert(res.status == 200) + if not res then + ngx.log(ngx.ERR, err) + return + end + + ngx.say("done") + } + } +--- response_body +done +--- error_log +route cache key: L2hlbGxvAEdFVAAxMjcuMC4wLjE= From df380b86e009346c51b02320252e3591f8fb3d18 Mon Sep 17 00:00:00 2001 From: kingluo Date: Wed, 19 Oct 2022 00:19:11 +0800 Subject: [PATCH 08/11] fix PR --- apisix/core/ai.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index b3496f5657da..40197fa4875a 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -19,6 +19,7 @@ local core = require("apisix.core") local ipairs = ipairs local pcall = pcall local loadstring = loadstring +local encode_base64 = ngx.encode_base64 local get_cache_key_func local get_cache_key_func_def_render @@ -54,7 +55,7 @@ end local function ai_match(ctx) local key = get_cache_key_func(ctx) - core.log.info("route cache key: ", core.log.delay_exec(ngx.encode_base64, key)) + core.log.info("route cache key: ", core.log.delay_exec(encode_base64, key)) local ver = router.user_routes.conf_version local route_cache = route_lrucache(key, ver, match_route, ctx) From 3e87bf0039902d9dd147a418095429f648f6e5b5 Mon Sep 17 00:00:00 2001 From: kingluo Date: Wed, 19 Oct 2022 09:29:31 +0800 Subject: [PATCH 09/11] fix style --- apisix/core/ai.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index 40197fa4875a..f9352a2fe4eb 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -75,15 +75,17 @@ local function gen_get_cache_key_func(route_flags) local str = get_cache_key_func_def_render({route_flags = route_flags}) local func, err = loadstring(str) if func == nil then - return err + return false, err else local ok ok, get_cache_key_func = pcall(func) if not ok then local err = get_cache_key_func - return err + return false, err end end + + return true end @@ -119,8 +121,8 @@ function _M.routes_analyze(routes) core.log.info("use ai plane to match route") router.match = ai_match - local err = gen_get_cache_key_func(route_flags) - if err then + local ok, err = gen_get_cache_key_func(route_flags) + if not ok then core.log.error("generate get_cache_key_func failed:", err) router.match = orig_router_match end From 7ba74687af76deb6fd94a38f96528f27b6d3f4a1 Mon Sep 17 00:00:00 2001 From: kingluo Date: Wed, 19 Oct 2022 10:07:50 +0800 Subject: [PATCH 10/11] fix PR --- apisix/core/ai.lua | 12 ++++++------ t/core/ai.t | 33 +++------------------------------ 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index f9352a2fe4eb..9e13be8781de 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -26,12 +26,13 @@ local get_cache_key_func_def_render local get_cache_key_func_def = [[ return function(ctx) - return ctx.var.uri + local var = ctx.var + return var.uri {% if route_flags["methods"] then %} - .. "\0" .. ctx.var.method + .. "\0" .. var.method {% end %} {% if route_flags["host"] then %} - .. "\0" .. ctx.var.host + .. "\0" .. var.host {% end %} end ]] @@ -77,12 +78,11 @@ local function gen_get_cache_key_func(route_flags) if func == nil then return false, err else - local ok - ok, get_cache_key_func = pcall(func) + local ok, err = pcall(func) if not ok then - local err = get_cache_key_func return false, err end + get_cache_key_func = err end return true diff --git a/t/core/ai.t b/t/core/ai.t index 0f0cb70eb61a..14d4e7b10273 100644 --- a/t/core/ai.t +++ b/t/core/ai.t @@ -505,8 +505,7 @@ use ai plane to match route end ngx.sleep(1) - -- enable - do + for i = 1, 2 do local httpc = http.new() local res, err = httpc:request_uri(uri) assert(res.status == 200) @@ -516,14 +515,6 @@ use ai plane to match route end end - local httpc = http.new() - local res, err = httpc:request_uri(uri) - assert(res.status == 200) - if not res then - ngx.log(ngx.ERR, err) - return - end - ngx.say("done") } } @@ -563,8 +554,7 @@ route cache key: L2hlbGxv end ngx.sleep(1) - -- enable - do + for i = 1, 2 do local httpc = http.new() local res, err = httpc:request_uri(uri) assert(res.status == 200) @@ -574,14 +564,6 @@ route cache key: L2hlbGxv end end - local httpc = http.new() - local res, err = httpc:request_uri(uri) - assert(res.status == 200) - if not res then - ngx.log(ngx.ERR, err) - return - end - ngx.say("done") } } @@ -622,8 +604,7 @@ route cache key: L2hlbGxvAEdFVA== end ngx.sleep(1) - -- enable - do + for i = 1, 2 do local httpc = http.new() local res, err = httpc:request_uri(uri) assert(res.status == 200) @@ -633,14 +614,6 @@ route cache key: L2hlbGxvAEdFVA== end end - local httpc = http.new() - local res, err = httpc:request_uri(uri) - assert(res.status == 200) - if not res then - ngx.log(ngx.ERR, err) - return - end - ngx.say("done") } } From e5b3958f350b06aeeb789e0813f26c8c4ef82e28 Mon Sep 17 00:00:00 2001 From: kingluo Date: Wed, 19 Oct 2022 11:50:47 +0800 Subject: [PATCH 11/11] fix PR --- apisix/core/ai.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apisix/core/ai.lua b/apisix/core/ai.lua index 9e13be8781de..57a8a60e0e1b 100644 --- a/apisix/core/ai.lua +++ b/apisix/core/ai.lua @@ -78,11 +78,11 @@ local function gen_get_cache_key_func(route_flags) if func == nil then return false, err else - local ok, err = pcall(func) + local ok, err_or_function = pcall(func) if not ok then - return false, err + return false, err_or_function end - get_cache_key_func = err + get_cache_key_func = err_or_function end return true