写在前面

前面通过两篇文章的学习,已经对Nacos有了一个较为初步的认识和使用,接下来开始学习Nacos的Open API、数据持久化、监控、集群部署、Nacos Docker等知识。

Open API

我们知道Nacos提供了可视化界面,一般来说可视化的系统都提供了一套可供程序调用的API,自然Nacos也不例外。Nacos提供了一套较为完整的API接口,开发者可以通过这些接口便能很方便的基于Nacos进行二次开发。

配置管理

Nacos对于配置管理提供了4个接口,分别用于获取、监听、发布和删除配置,这里以获取配置接口为例进行介绍。

获取配置

请注意这里采用标准的API格式进行书写:
(1)描述:获取Nacos上的配置;
(2)请求类型:GET;
(3)请求URL/nacos/v1/cs/configs;
(4)请求参数

名称 类型 是否必须 描述
tenant string 租户信息 ,对应于Nacos的命名空间ID字段
dataId string 配置集ID
group string 配置分组
(5)返回配置
类型 描述
:——–: :—-:
string 配置值
(6)错误编码
错误代码 描述 语义
——– :—-: :—-:
400 Bad Request 客户端请求中的语法错误
403 Forbidden 没有权限
404 Not Found 无法找到资源
500 Internal Server Error 服务器内部错误
200 OK 正常
(7)示例
(a)请求示例:
1
curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=config-client.properties&group=DEFAULT_GROUP&tenant=public"


(b)返回结果:

1
configContent

服务发现

Nacos对于服务发现提供了17个接口,具体的点击 这里 进行查看,这里以查询实例列表接口、创建服务接口和更新实例的健康状态接口为例进行介绍。

查询实例列表

查询实例列表接口用于查询服务下的实例列表,请注意这里采用标准的API格式进行书写:
(1)描述:查询服务下的实例列表;
(2)请求类型:GET;
(3)请求URL/nacos/v1/ns/instance/list;
(4)请求参数

名称 类型 是否必须 描述
serviceName string 服务名称
groupName string 分组名称
namespaceId string 命名空间ID
clusters string,多个集群用逗号分隔 集群名称
healthyOnly boolean 否,默认为false 是否只返回健康实例
(5)示例
(a)请求示例:
1
curl -X GET 127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=config-client

(b)返回结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"dom": "config-client",
"cacheMillis": 1000,
"useSpecifiedURL": false,
"hosts": [{
"valid": true,
"marked": false,
"instanceId": "192.168.31.100-8888-DEFAULT-nacos.test.1",
"port": 8888,
"ip": "192.168.31.100",
"weight": 1.0,
"metadata": {}
}],
"checksum": "4ftdf6dd1175203a8afdade0e77a27cd1528787794594",
"lastRefTime": 1528787794594,
"env": "",
"clusters": ""
}
创建服务接口

请注意这里采用标准的API格式进行书写:
(1)描述:创建一个服务;
(2)请求类型:POST;
(3)请求URL/nacos/v1/ns/service;
(4)请求参数

名称 类型 是否必须 描述
serviceName 字符串 服务名
groupName 字符串 分组名
namespaceId 字符串 命名空间ID
protectThreshold 浮点数 保护阈值,取值0到1,默认0
metadata 字符串 元数据
selector JSON格式字符串 访问策略
(5)示例
(a)请求示例:
1
curl -X POST "127.0.0.1:8848/nacos/v1/ns/service?serviceName=config-client&metadata=ryc3dv1"

(b)返回结果:

1
ok

#####更新实例的健康状态
请注意这里采用标准的API格式进行书写:
(1)描述:更新实例的健康状态,请注意仅在集群的健康检查关闭时才生效,当集群配置了健康检查时,该接口会返回错误;
(2)请求类型:PUT;
(3)请求URL/nacos/v1/ns/health/instance;
(4)请求参数
|名称|类型|是否必须|描述|
|——–| —–:|:—-: |:—-: |
|namespaceId|字符串|否|命名空间ID|
serviceName|字符串|是|服务名|
groupName|字符串|否|分组名|
clusterName|字符串|否|集群名|
ip|字符串|是|服务实例IP|
port|int|是|服务实例port|
healthy|boolean|是|是否健康|
(5)示例
(a)请求示例:

1
curl -X PUT "http://127.0.0.1:8848/nacos/v1/ns/health/instance?port=8848&healthy=true&ip=192.168.31.100&serviceName=config-client&namespaceId=n1"

(b)返回结果:

1
ok

数据持久化

在前面我们学习了Nacos作为服务注册中心和配置中心时的相关基础知识,接下来学习Nacos一些较为高级的用法,如数据持久化、Nacos集群部署等,这些在实际工作中用的还是比较多。

在前面我们是直接从Nacos官网中下载了nacos-server-1.3.1文件后就直接通过在其bin目录使用startup.cmd命令或者双击startup.cmd运行文件来以单机模式运行Nacos服务端。

但是在实际工作中,为了保证服务的高可用和稳定性,一般都是以集群方式来部署Nacos。那么问题来了,我们是不是可以通过修改不同端口然后都以单机模式启动Nacos服务端,然后在客户端指定多个Nacos服务端节点就可以实现我们需要的高可用呢?答案是错误的,你可能要问了,之前我们在学习Eureka作为服务注册中心的时候,就是通过这种方式实现了Eureka Server的多节点,怎么对于Nacos集群就不能采用上述方式了呢?原因在于Eureka使用了分布式存储方式来解决数据持久化过程中出现的不一致问题,而Nacos采用的是集中式存储,因此直接采用类似于Eureka的部署方式会导致数据无法持久化。

通常正确的做法是在搭建Nacos集群之前,先将Nacos默认的嵌入式数据库修改为MySQL数据库,如果不修改该配置,那么启动多个默认的Nacos节点时,其数据存储存在一致性问题。为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,但是目前仅仅支持MySQL的存储。

Nacos配置MySQL存储

接下来介绍Nacos如何配置MySQL存储,主要分以下三个步骤:
第一步,安装MySQL数据库。开发者需要自行安装MySQL数据库,注意版本必须高于5.6.5;

第二步,初始化MySQL数据库。开发者可以发现在之前下载的nacos-server-1.3.1文件下的conf文件夹下有一个名为nacos-mysql.sql的数据库初始化文件,首先创建一个名为nacos_config的数据库,然后再执行该文件,之后会生成如下所示的数据表:

第三步,修改MySQL数据库配置文件。开发者需要修改conf文件夹下面的application.properties配置文件,在里面新增对于MySQL数据库的支持,如下所示:

1
2
3
4
5
6
7
8
9
spring.datasource.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=root

通过以上三步,Nacos数据持久化到MySQL数据库中的相关配置就完成了。

第四步,测试Nacos数据持久化。首先重启Nacos服务端,然后在浏览器地址中访问http://127.0.0.1:8848/nacos链接,账号和密码都是nacos,也就是之前nacos_config数据库中users数据表中的账户信息。接着新建一个配置,内容如下所示:

然后保存,并刷新数据库,可以看到数据已经存入到MySQL数据库中:

从上面的学习中,我们可以发现Nacos数据的持久化实现,与其他中间件相比,并没有采用分布式算法来解决存储的一致性问题,而是采用了较为常规的集中化存储方式。由于采用了单一的数据源方式,避免了分布式存储中存在的一致性问题,因此学习的成本较低,但是从部署的负责度和硬件投入成本来说,它与etcd、consul、zookeeper等这些通过算法方式解决一致性问题的中间件相比,就显得不足。

还有在引入MySQL存储的同时,由于多了一个中间件的存在,会对Nacos的整体性能造成影响,因此一般会对MySQL以集群方式部署,但是这种势必会提高企业成本。这么看来无论如何提高存储性能,其对Nacos集群本身可用性造成的影响是无法消除的,但是影响可能都是在企业的可接受范围内,因此具体情况还需要结合实际情况进行对待。

集群部署

请注意,在进行集群化部署之前,如果你需要将数据持久化到MySQL数据库中,还需要提前进行上述MySQL配置操作,之后再开始进行Nacos生产环境的集群部署学习,下面是Nacos集群的架构图:

第一步,阅读文档。点击阅读 官方文档,了解Nacos生产环境的集群部署知识。

第二步,预备环境准备。请确保jdk版本不低于1.8;Maven版本不低于3.2.1;注意Nacos集群要求Nacos节点不低于3个。

第三步,数据持久化配置。如果需要将数据持久化到MySQL数据库,还需要按照上面的操作要求配置MySQL信息。

第四步,修改Nacos集群配置文件。在之前的conf文件夹下有一个名为cluster.conf.example的配置文件,开发者可以复制该文件并将其修改为cluster.conf,然后打开该文件,将需要部署的Nacos实例的地址配置在该文件中。这里以本地不同端口启动3个Nacos服务端节点为例进行介绍,那么应该在cluster.conf配置文件中添加如下配置:

1
2
3
4
5
#it is ip
#example
127.0.0.1:8830
127.0.0.1:8831
127.0.0.1:8832

注意由于这里是学习,因此可以将Nacos节点部署在一台机器上,在实际企业生产环境中肯定是将Nacos配置在多台机器上,那么就要求Nacos节点必须不少于三个,且这些节点之间是可以互相访问的。

第五步,启动Nacos多节点实例。注意这里笔者针对上面介绍的两种情况进行介绍:
(a)本地学习部署。由于我们是在本地通过设置不同的端口来启动Nacos服务端实例,而Nacos服务端都是Nacos官方提供的,各项参数都配置完成,我们可以通过直接修改其配置文件进而实现我们的目的。复制bin文件夹下面的startup.cmd启动文件,将其名称修改为startup-{portNmuber}.cmd的形式,并在其中第76行新增如下配置:

1
set "JAVA_OPT=%JAVA_OPT% -Dserver.port={portNumber}"

这样就有了三个对应的文件,如上面的8830端口对于的配置文件,然后就可以直接启动对应的配置文件来启动相应的Nacos服务端节点。

(b)企业生产部署。在企业生产环境部署的时候,由于每个实例节点都是分布在不同的节点上,除非需要修改一些JVM配置,否则就可以直接使用默认的启动脚本,因此直接在各自Nacos节点的bin文件夹下直接运行startup.cmd启动脚本文件即可。

Proxy配置

上面尽管搭建起了Nacos服务端集群,但是还有一个问题就是没有实现负载均衡功能,还记得之前的那个架构图:

可以看到里面有一个VIP,当外部请求访问的时候,需要通过这个VIP来根据负载均衡策略来指定调用哪个Nacos服务来处理请求,负载均衡的实现方式有很多种,最常用的就是Nginx,因此接下来就尝试使用Nginx来实现上述Nacos服务端节点的负载均衡。

打开Nginx软件conf文件夹下面的nginx.conf文件,在其http段中添加如下配置信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
http {
upstream nacosserver {
server 127.0.0.1:8830;
server 127.0.0.1:8831;
server 127.0.0.1:8832;
}

server {
listen 8080;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;

location /nacos/ {
proxy_pass http://nacosserver/nacos/;
}
}

请注意这里需要先添加一个upstream后面的名称为nacosserver,这个名称可以随意但是中间不能有下划线,然后在里面通过server来配置之前搭建的三个Nacos服务端节点地址信息。之后在下面的server片段中配置端口为8080,这个是nginx启动所占用的端口,然后配置server_name为localhost表示nginx启动是在本地运行的,而后面的location中配置的是当你访问本地的/nacos/接口时应该将那些请求转发到该接口显示页面,这里通过proxy_pass关键词设置地址为http://nacosserver/nacos/,看到了么这就是之前upstream中的地址。这段配置表达的意思是,当开发者在本地启动nginx后,在浏览器访问http://127.0.0.1:8080/nacos链接时,请求会将http://127.0.0.1:8830/nacoshttp://127.0.0.1:8831/nacoshttp://127.0.0.1:8832/nacos这三者中的任意一个页面进行转发,这样就实现了负载均衡功能:

注意这里没有配置upstream的具体策略,其默认会采用线性轮询的方式,如果后期开发者有需要,可以为其设置较为复杂的分发策略,但是不是Nacos的学习重点,而是Nginx的相关内容,这部分会在学习Nginx的时候进行介绍。

当然由于Nacos既是服务注册中心,又是配置中心,因此上述方式实现的负载均衡两个功能都可以实现。

总结

通过三篇文章的学习,我们已经可以灵活使用Nacos来作为服务注册中心和配置中心进而实现我们的既定需求。相信大家也都看到Nacos较Eureka相比,学习难度不大,且身兼数职,可以很好的实现我们的需求。但是由于其没有采用分布式存储设计,使得它在数据持久化方面会对系统整体性能带来一定的影响。也就是说Nacos除了自身以外,还需要借助于其他的一些中间件来完成某些功能,如前面说的持久化,这和Eureka相比就显得有些不足,这一点是团队领导者在前期做技术选型的时候必须考虑的。

那么这样关于Nacos的学习就先学到这里,后续会学习其他更加深入的知识。