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 14 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
47 changes: 33 additions & 14 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 @@ -233,15 +235,11 @@ local function iter_and_add_service(services, values)
up = conf
end

local namespace_id
if up.discovery_args then
namespace_id = up.discovery_args.namespace_id
end
local namespace_id = (up.discovery_args and up.discovery_args.namespace_id)
or default_namespace_id

local group_name
if up.discovery_args then
group_name = up.discovery_args.group_name
end
local group_name = (up.discovery_args and up.discovery_args.group_name)
or default_group_name

if up.discovery_type == 'nacos' then
core.table.insert(services, {
Expand Down Expand Up @@ -295,8 +293,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
local group_name = service_info.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 +307,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]
if not nodes then
nodes = {}
up_apps[service_info.service_name] = nodes
up_apps[namespace_id]
[group_name][service_info.service_name] = nodes
end
core.table.insert(nodes, {
host = host.ip,
Expand All @@ -335,7 +345,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 +363,11 @@ function _M.nodes(service_name)
ngx.sleep(step)
waiting_time = waiting_time - step
end
return applications[service_name]

if not applications[namespace_id] or not applications[namespace_id][group_name] then
return nil
end
return 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
14 changes: 9 additions & 5 deletions ci/install-ext-services-via-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,18 @@ mkdir tmp
cd tmp
wget https://raw.githubusercontent.com/api7/nacos-test-service/main/spring-nacos-1.0-SNAPSHOT.jar
curl https://raw.githubusercontent.com/api7/nacos-test-service/main/Dockerfile | docker build -t nacos-test-service:1.0-SNAPSHOT -f - .
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env DISCOVERY_PORT=18001 --env NACOS_ADDR=nacos2:8848 --env SUFFIX_NUM=1 -p 18001:18001 --name nacos-service1 nacos-test-service:1.0-SNAPSHOT
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env DISCOVERY_PORT=18002 --env NACOS_ADDR=nacos2:8848 --env SUFFIX_NUM=2 -p 18002:18001 --name nacos-service2 nacos-test-service:1.0-SNAPSHOT
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env SUFFIX_NUM=1 -p 18001:18001 --name nacos-service1 nacos-test-service:1.0-SNAPSHOT
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env SUFFIX_NUM=2 -p 18002:18001 --name nacos-service2 nacos-test-service:1.0-SNAPSHOT
# register nacos service with namespaceId=test_ns
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env DISCOVERY_PORT=18003 --env NACOS_ADDR=nacos2:8848 --env NAMESPACE=test_ns --env SUFFIX_NUM=1 -p 18003:18001 --name nacos-service3 nacos-test-service:1.0-SNAPSHOT
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env NAMESPACE=test_ns --env SUFFIX_NUM=1 -p 18003:18001 --name nacos-service3 nacos-test-service:1.0-SNAPSHOT
# register nacos service with group=test_group
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env DISCOVERY_PORT=18004 --env NACOS_ADDR=nacos2:8848 --env GROUP=test_group --env SUFFIX_NUM=1 -p 18004:18001 --name nacos-service4 nacos-test-service:1.0-SNAPSHOT
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env GROUP=test_group --env SUFFIX_NUM=1 -p 18004:18001 --name nacos-service4 nacos-test-service:1.0-SNAPSHOT
# register nacos service with namespaceId=test_ns and group=test_group
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env DISCOVERY_PORT=18005 --env NACOS_ADDR=nacos2:8848 --env NAMESPACE=test_ns --env GROUP=test_group --env SUFFIX_NUM=1 -p 18005:18001 --name nacos-service5 nacos-test-service:1.0-SNAPSHOT
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env NAMESPACE=test_ns --env GROUP=test_group --env SUFFIX_NUM=1 -p 18005:18001 --name nacos-service5 nacos-test-service:1.0-SNAPSHOT
# register nacos service with namespaceId=test_ns and group=test_group2
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env NAMESPACE=test_ns --env GROUP=test_group2 --env SUFFIX_NUM=3 -p 18006:18001 --name nacos-service6 nacos-test-service:1.0-SNAPSHOT
# register nacos service with namespaceId=test_ns2 and group=test_group
docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env NAMESPACE=test_ns2 --env GROUP=test_group --env SUFFIX_NUM=4 -p 18007:18001 --name nacos-service7 nacos-test-service:1.0-SNAPSHOT

url="127.0.0.1:18005/hello"
until [[ "$(curl -s -o /dev/null -w ''%{http_code}'' $url)" == "200" ]]; do
Expand Down
184 changes: 184 additions & 0 deletions t/discovery/nacos.t
Original file line number Diff line number Diff line change
Expand Up @@ -758,3 +758,187 @@ 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-service5
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",
"group_name": "test_group"
}
}
}]]
)

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

-- use nacos-service6
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_group2"
}
},
"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
ngx.say(res.body)

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(res.body)
}
}
--- request
GET /t
--- response_body
server 1
server 3
--- 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-service5
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",
"group_name": "test_group"
}
}
}]]
)

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

-- use nacos-service7
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_ns2",
"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
ngx.say(res.body)

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(res.body)
}
}
--- request
GET /t
--- response_body
server 1
server 4
--- no_error_log
[error]