Skip to content

feat: add nacos support#3820

Merged
spacewander merged 66 commits into
apache:masterfrom
benx203:master
Apr 21, 2021
Merged

feat: add nacos support#3820
spacewander merged 66 commits into
apache:masterfrom
benx203:master

Conversation

@benx203

@benx203 benx203 commented Mar 13, 2021

Copy link
Copy Markdown
Contributor

feat:add nacos support

add nacos support

@spacewander spacewander left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add test under t/discovery.

@spacewander

Copy link
Copy Markdown
Member

@benx203 benx203 changed the title add nacos support feat:add nacos support Mar 15, 2021
@spacewander spacewander changed the title feat:add nacos support feat: add nacos support Mar 15, 2021
@spacewander

Copy link
Copy Markdown
Member

Please make sure it can pass the lint.

Comment thread docs/en/latest/discovery/nacos.md Outdated
discovery:
nacos:
host:
- "http://192.168.33.1:8848"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't mention the user / password feature?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because Nacos not need login yet.

Comment thread apisix/discovery/nacos.lua Outdated
},
fetch_interval = {type = "integer", minimum = 1, default = 30},
prefix = {type = "string"},
weight = {type = "integer", minimum = 0},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing default for weight?
And the minimum weight should be 1.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK,I copy from eureka.

Comment thread apisix/discovery/nacos.lua Outdated

local httpc = http.new()
local timeout = local_conf.discovery.nacos.timeout
local connect_timeout = timeout and timeout.connect or 2000

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default value will be injected via schema check. We don't need to assign it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

Comment thread apisix/discovery/nacos.lua Outdated
log.info("default_weight:", default_weight, ".")
local fetch_interval = local_conf.discovery.nacos.fetch_interval or 30
log.info("fetch_interval:", fetch_interval, ".")
service_list_path = local_conf.discovery.nacos.service_list_path or

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where should I configure service_list_path? There is neither schema nor doc for it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will fix it.

Comment thread apisix/discovery/nacos.lua Outdated
log.info("fetch_interval:", fetch_interval, ".")
service_list_path = local_conf.discovery.nacos.service_list_path or
'ns/service/list?pageNo=1&pageSize=20'
instance_list_path = local_conf.discovery.nacos.instance_list_path or

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Comment thread apisix/discovery/nacos.lua Outdated
end

local up_apps = core.table.new(0, 0)
local data = get_url(base_uri,basic_auth,service_list_path)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need space after the comma.
And please check the returned value of get_url.

Comment thread apisix/discovery/nacos.lua Outdated
log.info("nacos uri:", request_uri, ".")
local url = request_uri .. path
local headers = core.table.new(0, 5)
headers['Connection'] = 'Keep-Alive'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need it for HTTP 1.1

Comment thread apisix/discovery/nacos.lua Outdated
local function request(request_uri, basic_auth, method, path, query, body)
log.info("nacos uri:", request_uri, ".")
local url = request_uri .. path
local headers = core.table.new(0, 5)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why choose 5?

Comment thread apisix/discovery/nacos.lua Outdated
if local_conf.discovery.nacos.prefix then
url = url .. local_conf.discovery.nacos.prefix
end
if string_sub(url, #url) ~= "/" then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to use str_byte(uri, #uri) == str_byte("/")

Comment thread apisix/discovery/nacos.lua Outdated
Comment thread docs/en/latest/discovery/nacos.md Outdated
fetch_interval: 30 # default 30 sec
weight: 100 # default 100
timeout:
connect: 2000 # default 2000

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to mention the unit is ms.

Comment thread t/discovery/nacos.t Outdated
--- pipelined_requests eval
[
"POST /nacos/v1/ns/instance?port=18001&healthy=true&ip=127.0.0.1&weight=1.0&serviceName=APISIX-NACOS&encoding=GBK&enabled=true",
"DELETE /nacos/v1/ns/service?serviceName=APISIX-NACOS",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why POST and then DELETE?

@benx203 benx203 Mar 23, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If has no data,delete return code is 400,if has data,delete return code is 200.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it is not the feature of APISIX. We don't need to test nacos itself.

Comment thread t/discovery/nacos.t Outdated
#END
--- request
GET /hello
--- error_code: 200

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to show if server 1 or server 2 is hit.
And we need a test to show the default weight

Comment thread docs/en/latest/discovery/nacos.md Outdated
```shell
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
{
"uri": "/nacos/**",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use /nacos/* is enough?

Comment thread .travis/linux_tengine_runner.sh Outdated
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data

# start nacos server
docker run --rm --name nacos_1 -d --env PREFER_HOST_MODE=hostname --env MODE=standalone --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need test the user/password feature.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If add NACOS_AUTH_ENABLE=true, file nacos.t need login too.
Could you give me a t file login demo?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use different conf in different tests, one for auth success and another for auth fail.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to check nacos in discovery plugin whether authed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the auth enable nacos can be used, the auth is successful.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if nacos start with auth mode,in nacos.t add services to nacos need send auth token.
How can i save auth token in nacos.t?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread apisix/discovery/nacos.lua Outdated
}


local function str_split (inputstr, sep)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use existent API:

local levels = ngx_re.split(cache_levels, ":")

Comment thread apisix/discovery/nacos.lua Outdated
prefix = {type = "string", default = "/nacos/v1/"},
auth_path = {type = "string", default = "auth/login"},
service_list_path = {type = "string", default = "ns/service/list?pageNo=1&pageSize=20"},
instance_list_path = {type = "string", default = "ns/instance/list?serviceName="},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a test to check the user-defined paths.
BTW, in what situation people need to redefine the paths?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When Nacos api change.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benx203
I think we can remove it now and add it if needed.
We need to add a doc and test for this feature if you insist to keep it.
(I don't recommend to do that as this PR is big enough)

Comment thread apisix/discovery/nacos.lua
Comment thread apisix/discovery/nacos.lua Outdated
fetch_interval = {type = "integer", minimum = 1, default = 30},
prefix = {type = "string", default = "/nacos/v1/"},
auth_path = {type = "string", default = "auth/login"},
service_list_path = {type = "string", default = "ns/service/list?pageNo=1&pageSize=20"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only return the first 20 services is not a good idea.
We need to iterate the upstreams and build a service list from those that have nacos discovery_type.
Like this:

values = get_upstreams()
else
return 400, {error_msg = str_format("invalid src type %s", src_type)}
end
local info, err = iter_and_find_healthcheck_info(values, src_type, src_id)

You might need some lazy load trick to break the dependent cycle.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

Comment thread apisix/discovery/nacos.lua Outdated
end

for _, host in ipairs(data.hosts) do
if tostring(host.valid) == 'true' and

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I set up the environment and debug it myself.
Here is the host: {"enabled":true,"instanceHeartBeatTimeOut":15000,"ipDeleteTimeout":30000,"instanceHeartBeatInterval":5000,"metadata":{"preserved.register.source":"SPRING_CLOUD"},"port":18001,"serviceName":"DEFAULT_GROUP@@APISIX-NACOS","instanceId":"192.168.65.3#18001#DEFAULT#DEFAULT_GROUP@@APISIX-NACOS","healthy":true,"ip":"192.168.65.3","ephemeral":true,"clusterName":"DEFAULT","weight":1}

There is not valid field. The response doesn't match their API doc: https://nacos.io/en-us/docs/open-api.html

I am not sure if it is because the latest Nacos has changed the API. Maybe we need to use the tagged nacos image 2.0.0 instead of the latest one?

Comment thread .github/workflows/centos7-ci.yml Outdated
nohup docker network rm nacos_net > /dev/null 2>&1 &
nohup docker network create nacos_net > /dev/null 2>&1 &
# nacos no auth server - for test no auth
docker run --rm -d --name nacos_no_auth --network nacos_net --hostname nacos2 --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8858:8848 nacos/nacos-server:latest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to use nacos/nacos-server:2.0.0?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nacos version should be 1.4.1,2.0.0 just released few days ago.

@spacewander spacewander Apr 8, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benx203
Why can't we support 2.0.0 directly? Is 2.0.0 incompatible with 1.4.1?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think better way is support both 2.0.0 and 1.4.1.
Maybe support 2.0.0 later?

Comment thread .github/workflows/centos7-ci.yml Outdated
rm -rf tmp
mkdir tmp
cd tmp
wget https://raw.githubusercontent.com/benx203/nacos-test-service/main/spring-nacos-1.0-SNAPSHOT.jar

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

Comment thread apisix/discovery/nacos.lua Outdated
for _, host in ipairs(data.hosts) do
if tostring(host.valid) == 'true' and
tostring(host.healthy) == 'true' and
tostring(host.enabled) == 'true' then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more question: why we need to filter the result according to those fields?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If query all records,need to filter.
But now should not need any more.

@spacewander

Copy link
Copy Markdown
Member

@benx203
I will work on this PR and fulfill my promise in a few days. Please be patient.

@benx203

benx203 commented Apr 9, 2021

Copy link
Copy Markdown
Contributor Author

@spacewander
OK.Take your time.

Signed-off-by: spacewander <[email protected]>
Signed-off-by: spacewander <[email protected]>
Comment thread apisix/discovery/nacos.lua Outdated
type = "array",
minItems = 1,
items = {
type = "string",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a pattern to limit the string to the host format

Comment thread apisix/discovery/nacos.lua Outdated
},
},
fetch_interval = {type = "integer", minimum = 1, default = 30},
prefix = {type = "string", default = "/nacos/v1/"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Comment thread apisix/discovery/nacos.lua Outdated


local _M = {
version = 0.1,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this version is useless, we can drop it

local url = request_uri .. path
log.info("request url:", url)
local headers = core.table.new(0, 0)
headers['Accept'] = 'application/json'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the string object, I think we use ", it is easier for reading.

headers["Accept"] = "application/json"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and please fix the similar points

Comment thread apisix/discovery/nacos.lua Outdated


local function get_token_param(base_uri, username, password)
if username and password then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better style:

if not username or not password then
    return ""
end

...

Comment thread apisix/discovery/nacos.lua Outdated

local function get_token_param(base_uri, username, password)
if username and password then
local data, err = post_url(base_uri, auth_path .. "?username=" .. username

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should call ngx.encode_args for username and password

Comment thread apisix/discovery/nacos.lua Outdated


local function iter_and_add_service(services, values)
if not values then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bad indentation

Comment thread apisix/discovery/nacos.lua Outdated
local host = local_conf.discovery.nacos.host
-- TODO Add health check to get healthy nodes.
local url = host[math_random(#host)]
local auth_idx = str_find(url, "@")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread apisix/discovery/nacos.lua Outdated

function _M.nodes(service_name)
local logged = false
while not applications do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to set a maximum waiting time , eg: 5 seconds

@moonming

Copy link
Copy Markdown
Member

@benx203 thanks for your contribution.
You can create a new PR to fix the code style issue.
And it will be better if you can add support Nacos in the README.md to let more people know about this feature.

@benx203

benx203 commented Apr 15, 2021

Copy link
Copy Markdown
Contributor Author

@benx203 thanks for your contribution.
You can create a new PR to fix the code style issue.
And it will be better if you can add support Nacos in the README.md to let more people know about this feature.

OK,i will try,thank you all.

Comment thread apisix/discovery/nacos.lua Outdated


function _M.nodes(service_name)
local logged = false

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original code is good. We just need to set a 5s limitation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just keep simple.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lazy init is important as the sync is slow.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK,i rollback the code.

Comment thread apisix/discovery/nacos.lua Outdated
local host = local_conf.discovery.nacos.host
-- TODO Add health check to get healthy nodes.
local url = host[math_random(#host)]
local auth_idx = str_find(url, '@', 1, true)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core.string.find is already the plain string find... 😅
Not all the suggestion from the reviewer is correct.

local values = get_upstreams()
iter_and_add_service(services, values)
values = get_routes()
iter_and_add_service(services, values)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way,Are there 'discovery_type' config in service and route?
@spacewander

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those can have embedded upstream field.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see,thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants