Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(nacos): distinguish services that has same name but in different groups or namespaces #5083

Merged
merged 16 commits into from
Sep 23, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions apisix/discovery/nacos.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ local default_weight
local applications
local auth_path = 'auth/login'
local instance_list_path = 'ns/instance/list?healthyOnly=true&serviceName='
local default_namespace_id = "public"
local default_group_name = "DEFAULT_GROUP"

local events
local events_list
Expand Down Expand Up @@ -235,12 +237,12 @@ local function iter_and_add_service(services, values)

local namespace_id
if up.discovery_args then
namespace_id = up.discovery_args.namespace_id
namespace_id = up.discovery_args.namespace_id or default_namespace_id
tzssangglass marked this conversation as resolved.
Show resolved Hide resolved
end

local group_name
if up.discovery_args then
group_name = up.discovery_args.group_name
group_name = up.discovery_args.group_name or default_group_name
end

if up.discovery_type == 'nacos' then
Expand Down Expand Up @@ -295,8 +297,10 @@ local function fetch_full_registry(premature)
end
local data, err
for _, service_info in ipairs(infos) do
local namespace_param = get_namespace_param(service_info.namespace_id)
local group_name_param = get_group_name_param(service_info.group_name)
local namespace_id = service_info.namespace_id or default_namespace_id
local group_name = service_info.group_name or default_group_name
local namespace_param = get_namespace_param(namespace_id)
local group_name_param = get_group_name_param(group_name)
data, err = get_url(base_uri, instance_list_path .. service_info.service_name
.. token_param .. namespace_param .. group_name_param)
if err then
Expand All @@ -307,11 +311,21 @@ local function fetch_full_registry(premature)
return
end

if not up_apps[namespace_id] then
up_apps[namespace_id] = {}
end

if not up_apps[namespace_id][group_name] then
up_apps[namespace_id][group_name] = {}
end

for _, host in ipairs(data.hosts) do
local nodes = up_apps[service_info.service_name]
local nodes = up_apps[namespace_id]
[group_name][service_info.service_name]
tzssangglass marked this conversation as resolved.
Show resolved Hide resolved
tzssangglass marked this conversation as resolved.
Show resolved Hide resolved
if not nodes then
nodes = {}
up_apps[service_info.service_name] = nodes
up_apps[namespace_id]
[group_name][service_info.service_name] = nodes
tzssangglass marked this conversation as resolved.
Show resolved Hide resolved
end
core.table.insert(nodes, {
host = host.ip,
Expand All @@ -335,7 +349,12 @@ local function fetch_full_registry(premature)
end


function _M.nodes(service_name)
function _M.nodes(service_name, discovery_args)
local namespace_id = discovery_args and
discovery_args.namespace_id or default_namespace_id
local group_name = discovery_args
and discovery_args.group_name or default_group_name

local logged = false
-- maximum waiting time: 5 seconds
local waiting_time = 5
Expand All @@ -348,7 +367,8 @@ function _M.nodes(service_name)
ngx.sleep(step)
waiting_time = waiting_time - step
end
return applications[service_name]
return applications[namespace_id] and applications[namespace_id][group_name] and
applications[namespace_id][group_name][service_name]
end


Expand Down
2 changes: 1 addition & 1 deletion apisix/upstream.lua
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ function _M.set_by_route(route, api_ctx)
return 503, err
end

local new_nodes, err = dis.nodes(up_conf.service_name)
local new_nodes, err = dis.nodes(up_conf.service_name, up_conf.discovery_args)
if not new_nodes then
return HTTP_CODE_UPSTREAM_UNAVAILABLE, "no valid upstream node: " .. (err or "nil")
end
Expand Down
192 changes: 192 additions & 0 deletions t/discovery/nacos.t
Original file line number Diff line number Diff line change
Expand Up @@ -758,3 +758,195 @@ discovery:
]
--- no_error_log
[error]



=== TEST 25: same namespace_id and service_name, different group_name
--- extra_yaml_config
discovery:
nacos:
host:
- "http://127.0.0.1:8858"
fetch_interval: 1
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test

-- use nacos-service3, NAMESPACE=test_ns and use default group_name
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"uri": "/hello",
"upstream": {
"service_name": "APISIX-NACOS",
"discovery_type": "nacos",
"type": "roundrobin",
"discovery_args": {
"namespace_id": "test_ns"
}
}
}]]
)

if code >= 300 then
ngx.status = code
end

-- use nacos-service5, NAMESPACE=test_ns and group_name=test_group
local code, body = t('/apisix/admin/routes/2',
ngx.HTTP_PUT,
[[{
"uri": "/hello1",
"upstream": {
"service_name": "APISIX-NACOS",
"discovery_type": "nacos",
"type": "roundrobin",
"discovery_args": {
"namespace_id": "test_ns",
"group_name": "test_group"
}
},
"plugins": {
"proxy-rewrite": {
"uri": "/hello"
}
}
}]]
)

if code >= 300 then
ngx.status = code
end

ngx.sleep(1.5)

local http = require "resty.http"
local httpc = http.new()
local uri1 = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
local res, err = httpc:request_uri(uri1, { method = "GET"})
if err then
ngx.log(ngx.ERR, err)
ngx.status = res.status
return
end

local uri2 = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello1"
res, err = httpc:request_uri(uri2, { method = "GET"})
if err then
ngx.log(ngx.ERR, err)
ngx.status = res.status
return
end
ngx.say("passed")
}
}
--- request
GET /t
--- wait: 2
--- timeout: 4
--- response_body
passed
--- grep_error_log eval
qr/proxy request to \S+ while connecting to upstream.*\"GET \/hello.* HTTP\/1.1\"/
--- grep_error_log_out
proxy request to 127.0.0.1:18003 while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /hello HTTP/1.1"
proxy request to 127.0.0.1:18005 while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /hello1 HTTP/1.1"
--- no_error_log
[error]



=== TEST 26: same group_name and service_name, different namespace_id
--- extra_yaml_config
discovery:
nacos:
host:
- "http://127.0.0.1:8858"
fetch_interval: 1
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test

-- use nacos-service4, group_name=test_group and use default namespace_id
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"uri": "/hello",
"upstream": {
"service_name": "APISIX-NACOS",
"discovery_type": "nacos",
"type": "roundrobin",
"discovery_args": {
"group_name": "test_group"
}
}
}]]
)

if code >= 300 then
ngx.status = code
end

-- use nacos-service5, NAMESPACE=test_ns and group_name=test_group
local code, body = t('/apisix/admin/routes/2',
ngx.HTTP_PUT,
[[{
"uri": "/hello1",
"upstream": {
"service_name": "APISIX-NACOS",
"discovery_type": "nacos",
"type": "roundrobin",
"discovery_args": {
"namespace_id": "test_ns",
"group_name": "test_group"
}
},
"plugins": {
"proxy-rewrite": {
"uri": "/hello"
}
}
}]]
)

if code >= 300 then
ngx.status = code
end

ngx.sleep(1.5)

local http = require "resty.http"
local httpc = http.new()
local uri1 = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
local res, err = httpc:request_uri(uri1, { method = "GET"})
if err then
ngx.log(ngx.ERR, err)
ngx.status = res.status
return
end

local uri2 = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello1"
res, err = httpc:request_uri(uri2, { method = "GET"})
if err then
ngx.log(ngx.ERR, err)
ngx.status = res.status
return
end
ngx.say("passed")
}
}
--- request
GET /t
--- wait: 2
--- timeout: 4
--- response_body
passed
--- grep_error_log eval
qr/proxy request to \S+ while connecting to upstream.*\"GET \/hello.* HTTP\/1.1\"/
--- grep_error_log_out
proxy request to 127.0.0.1:18004 while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /hello HTTP/1.1"
proxy request to 127.0.0.1:18005 while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /hello1 HTTP/1.1"
--- no_error_log
[error]