Skip to content

Commit

Permalink
fix(nacos): distinguish services that has same name but in different …
Browse files Browse the repository at this point in the history
…groups or namespaces (#5083)
  • Loading branch information
tzssangglass authored Sep 23, 2021
1 parent 8d69af5 commit 2ead265
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 18 deletions.
43 changes: 31 additions & 12 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 @@ -296,6 +294,8 @@ local function fetch_full_registry(premature)

for _, service_info in ipairs(infos) do
local data, err
local namespace_id = service_info.namespace_id
local group_name = service_info.group_name
local namespace_param = get_namespace_param(service_info.namespace_id)
local group_name_param = get_group_name_param(service_info.group_name)
local query_path = instance_list_path .. service_info.service_name
Expand All @@ -306,11 +306,21 @@ local function fetch_full_registry(premature)
goto CONTINUE
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 @@ -336,7 +346,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 @@ -349,7 +364,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]

0 comments on commit 2ead265

Please sign in to comment.