文章目录
什么是 Nacos
- Nacos 是服务注册中心,是阿里巴巴推出来的一个新开源项目,是致力于帮助我们发现、配置和管理微服务的。
- Nacos 提供了一组简单易用的特性集,帮助快速实现动态服务发现、服务配置、服务元数据及流量管理。
- Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
相对于 Spring Cloud Eureka 来说,Nacos 更强大。Nacos = Spring Cloud Eureka + Spring Cloud Config - Nacos 可以与 Spring, Spring Boot, Spring Cloud 集成,并能代替 Spring Cloud Eureka, Spring Cloud Config
- 通过
Nacos Serve
r 和spring-cloud-starter-alibaba-nacos-config
实现配置的动态变更 - 通过
Nacos Server
和spring-cloud-starter-alibaba-nacos-discovery
实现服务的注册与发现
Nacos能做什么。
- Nacos是以服务为主要服务对象的中间件,Nacos支持所有主流的服务发现、配置和管理。
- Nacos主要提供以下四大功能:
- 服务发现和服务健康监测
- 动态配置服务
- 动态DNS服务
- 服务及其元数据管理
注册中心原理
在使用注册中心时,一共有三种角色:服务提供者(Service Provider
)、服务消费者(Service Consumer
)、注册中心(Registry
)。
三个角色交互如下图所示:
① Provider:
- 启动时,向 Registry 注册自己为一个服务(Service)的实例(Instance)。
- 同时,定期向 Registry 发送心跳,告诉自己还存活。
- 关闭时,向 Registry 取消注册。
② Consumer:
- 启动时,向 Registry 订阅使用到的服务,并缓存服务的实例列表在内存中。
- 后续,Consumer 向对应服务的 Provider 发起调用时,从内存中的该服务的实例列表选择一个,进行远程调用。
- 关闭时,向 Registry 取消订阅。
③ Registry:
- Provider 超过一定时间未心跳时,从服务的实例列表移除。
*服务的实例列表发生变化(新增或者移除)时,通知订阅该服务的 Consumer,从而让 Consumer 能够刷新本地缓存。
Provider
和Consumer
是角色上的定义,一个服务同时即可以是 Provider 也可以作为 Consumer。例如说,优惠劵服务可以给订单服务提供接口,同时又调用用户服务提供的接口。
构建应用接入Nacos注册中心
服务提供者
第一步:创建一个Spring Boot应用,可以命名为:alibaba-nacos-discovery-server。作为服务提供者 demo-provider
第二步:编辑pom.xml,加入必要的依赖配置,比如:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>labx-01</artifactId>
<groupId>cn.iocoder.springboot.labs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>alibaba-nacos-discovery-server</artifactId>
<properties>
<spring.boot.version>2.2.4.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR1</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version>
</properties>
<!--
引入 Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者 BOM 文件,进行依赖版本的管理,防止不兼容。
在 https://dwz.cn/mcLIfNKt 文章中,Spring Cloud Alibaba 开发团队推荐了三者的依赖关系
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入 SpringMVC 相关依赖,并实现对其的自动配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入 Spring Cloud Alibaba Nacos Discovery 相关依赖,将 Nacos 作为注册中心,并实现对其的自动配置 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
</project>
在 <dependencyManagement />
中,我们引入了 Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者 BOM 文件,进行依赖版本的管理,防止不兼容。在《Spring Cloud 官方文档 —— 版本说明》文档中,推荐了三者的依赖关系。如下表格:
- 这里,我们选择了 Spring Cloud Alibaba 版本为 2.2.0.RELEASE。
- 当前版版本下,我们使用的 Nacos 版本为 1.1.4。
引入spring-cloud-starter-alibaba-nacos-discovery
依赖,将 Nacos 作为注册中心,并实现对它的自动配置。
第三步,配置文件
创建 application.yaml
配置文件,添加 Nacos Discovery
配置项。配置如下
spring:
application:
name: demo-provider # Spring 应用名
cloud:
nacos:
# Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类
discovery:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。
server:
port: 18080 # 服务器端口。默认为 8080
重点看 spring.cloud.nacos.discovery
配置项,它是 Nacos Discovery 配置项的前缀,对应 NacosDiscoveryProperties
配置项。
第四步,创建应用启动类,并提供 HTTP 接口。
@SpringBootApplication
@EnableDiscoveryClient
public class DemoProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DemoProviderApplication.class, args);
}
@RestController
static class TestController {
@GetMapping("/echo")
public String echo(String name) {
return "provider:" + name;
}
}
}
①@SpringBootApplication
注解,被添加在类上,声明这是一个 Spring Boot 应用。Spring Cloud 是构建在 Spring Boot 之上的,所以需要添加。
② @EnableDiscoveryClient
注解,开启 Spring Cloud 的注册发现功能
。不过从 Spring Cloud Edgware 版本开始,实际上已经不需要添加 @EnableDiscoveryClient 注解,只需要引入 Spring Cloud 注册发现组件,就会自动开启注册发现的功能。例如说,我们这里已经引入了 spring-cloud-starter-alibaba-nacos-discovery 依赖,就不用再添加 @EnableDiscoveryClient 注解了。
③ TestController 类,提供了 /echo 接口,返回 provider:${name} 结果。
简单测试
① 通过 启动类启动服务提供者,IDEA 控制台输出日志如:
// ... 省略其它日志
2020-02-08 15:25:57.406 INFO 27805 --- [ main] c.a.c.n.registry.NacosServiceRegistry : nacos registry, DEFAULT_GROUP demo-provider 10.171.1.115:18080 register finished
- 服务
demo-provider
注册到 Nacos 上的日志。
② 在启动都ok之后,我们可以访问Nacos的管理页面http://127.0.0.1:8848/nacos/来查看服务列表,此时可以看到如下内容:
图片: https://uploader.shimo.im/f/fE17KttghvewpEzL.PNG!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDUyMDEzNDgsImciOiJ3VjNWVlhQd1ZwVXBqeTN5IiwiaWF0IjoxNjQ1MjAxMDQ4LCJ1c2VySWQiOjc0OTQ1MzI3fQ.C84lqfv5ZGn3s-zLc4XLOEm_rNWVpekOqFi0oF5yV3s
服务消费者
接下来,实现一个应用来消费上面已经注册到Nacos的服务。
第一步:创建一个Spring Boot应用,命名为:alibaba-nacos-discovery-client-common,作为服务消费者 demo-consumer。
第二步:编辑pom.xml中的依赖内容,与上面服务提供者的一样即可。
第三步,创建 application.yaml 配置文件,添加相应配置项。配置如下
spring:
application:
name: demo-consumer # Spring 应用名
cloud:
nacos:
# Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类
discovery:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
server:
port: 8081 # 服务器端口。默认为 8080
第三步:创建应用主类,并实现一个HTTP接口,在该接口中调用服务提供方的接口。
@EnableDiscoveryClient
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@Slf4j
@RestController
static class TestController {
@Autowired
LoadBalancerClient loadBalancerClient;
@GetMapping("/test")
public String test() {
// 通过spring cloud common中的负载均衡接口选取服务提供节点实现接口调用
ServiceInstance serviceInstance = loadBalancerClient.choose(“alibaba-nacos-discovery-server”);
String url = serviceInstance.getUri() + “/hello?name=” + “didi”;
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(url, String.class);
return "Invoke : " + url + ", return : " + result;
}
}
}
这里使用了Spring Cloud Common中的LoadBalancerClient接口来挑选服务实例信息。然后从挑选出的实例信息中获取可访问的URI,拼接上服务提供方的接口规则来发起调用
第五步,启动服务消费者,然后通过curl或者postman等工具发起访问,下面以curl为例:
$ curl localhost:9000/test
Invoke : http://10.123.18.216:8001/hello?name=didi, return : hello didi
$ curl localhost:9000/test
Invoke : http://10.123.18.216:8002/hello?name=didi, return : hello didi
可以看到,两次不同请求的时候,真正实际调用的服务提供者实例是不同的,也就是说,通过LoadBalancerClient接口在获取服务实例的时候,已经实现了对服务提供方实例的负载均衡。但是很明显,这样的实现还是比较繁琐,预告下后面的几篇,关于服务消费的几种不同姿势。
支持的几种服务消费方式
(RestTemplate、WebClient、Feign):https://blog.didispace.com/spring-cloud-alibaba-2/
Nacos作为配置中心
Nacos除了实现了服务的注册发现之外,还将配置中心功能整合在了一起。Nacos的配置管理模型与淘宝开源的配置中心Diamond类似,基础层面都通过DataId和Group来定位配置内容,除此之外还增加了很多其他的管理功能。
创建配置
第一步:进入Nacos的控制页面,在配置列表功能页面中,点击右上角的“+”按钮,进入“新建配置”页面,如下图填写内容:图片: https://uploader.shimo.im/f/KJNgfdDcu4CX6PQv.PNG!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDUyMDEzNDgsImciOiJ3VjNWVlhQd1ZwVXBqeTN5IiwiaWF0IjoxNjQ1MjAxMDQ4LCJ1c2VySWQiOjc0OTQ1MzI3fQ.C84lqfv5ZGn3s-zLc4XLOEm_rNWVpekOqFi0oF5yV3s
其中:
Data ID:填入alibaba-nacos-config-client.properties
Group:不修改,使用默认值DEFAULT_GROUP
配置格式:选择Properties
配置内容:应用要加载的配置内容,这里仅作为示例,做简单配置,比如:didispace.title=spring-cloud-alibaba-learning
创建应用
第一步:创建一个Spring Boot应用,可以命名为:alibaba-nacos-config-client。
第二步:编辑pom.xml,加入必要的依赖配置,比如:
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-alibaba-nacos-config
org.projectlombok
lombok
1.18.2
true
上述内容主要三部分:
parent:定义spring boot的版本
dependencyManagement:spring cloud的版本以及spring cloud alibaba的版本,由于spring cloud alibaba还未纳入spring cloud的主版本管理中,所以需要自己加入
dependencies:当前应用要使用的依赖内容。这里主要新加入了Nacos的配置客户端模块:spring-cloud-starter-alibaba-nacos-config。由于在dependencyManagement中已经引入了版本,所以这里就不用指定具体版本了。
可以看到,这个例子中并没有加入nacos的服务发现模块,所以这两个内容是完全可以独立使用的
第三步:创建应用主类,并实现一个HTTP接口:
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@Slf4j
@RestController
@RefreshScope
static class TestController {
@Value("${didispace.title:}")
private String title;
@GetMapping("/test")
public String hello() {
return title;
}
}
}
@SpringBootApplication定义是个Spring Boot应用;还定义了一个Controller,其中通过@Value注解,注入了key为didispace.title的配置(默认为空字符串),这个配置会通过/test接口返回,后续我们会通过这个接口来验证Nacos中配置的加载。另外,这里还有一个比较重要的注解@RefreshScope,主要用来让这个类下的配置内容支持动态刷新,也就是当我们的应用启动之后,修改了Nacos中的配置内容之后,这里也会马上生效。
第四步:创建配置文件bootstrap.properties,并配置服务名称和Nacos地址
spring.application.name=alibaba-nacos-config-client
server.port=8001
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
注意:这里必须使用bootstrap.properties。同时,spring.application.name值必须与上一阶段Nacos中创建的配置Data Id匹配(除了.properties或者.yaml后缀)。
第五步:启动上面创建的应用。
2019-01-27 18:29:43.497 INFO 93597 — [ main] o.s.c.a.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: ‘alibaba-nacos-config-client.properties’, group: ‘DEFAULT_GROUP’
2019-01-27 18:29:43.498 INFO 93597 — [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name=‘NACOS’, propertySources=[NacosPropertySource {name=‘alibaba-nacos-config-client.properties’}]}
在启动的时候,我们可以看到类似上面的日志信息,这里会输出应用程序要从Nacos中获取配置的dataId和group。如果在启动之后,发现配置信息没有获取到的时候,可以先从这里着手,看看配置加载的目标是否正确。
第六步:验证配置获取和验证动态刷新
用curl或者postman等工具,访问接口: localhost:8001/test,一切正常的话,将返回Nacos中配置的spring-cloud-alibaba-learning。然后,再通过Nacos页面,修改这个内容,点击发布之后,再访问接口,可以看到返回结果变了。
同时,在应用的客户端,我们还能看到如下日志:
2019-01-27 18:39:14.162 INFO 93597 — [-127.0.0.1_8848] o.s.c.e.event.RefreshEventListener : Refresh keys changed: [didispace.title]
在Nacos中修改了Key,在用到这个配置的应用中,也自动刷新了这个配置信息。
Nacos配置的加载规则详解
图片: https://uploader.shimo.im/f/0ST1eRTsunWNk91A.PNG!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDUyMDEzNDgsImciOiJ3VjNWVlhQd1ZwVXBqeTN5IiwiaWF0IjoxNjQ1MjAxMDQ4LCJ1c2VySWQiOjc0OTQ1MzI3fQ.C84lqfv5ZGn3s-zLc4XLOEm_rNWVpekOqFi0oF5yV3s
图中的Nacos中创建的配置内容是这样的:
Data ID:alibaba-nacos-config-client.properties
Group:DEFAULT_GROUP
拆解一下,主要有三个元素,它们与具体应用的配置内容对应关系如下:
Data ID中的alibaba-nacos-config-client:对应客户端的配置spring.cloud.nacos.config.prefix,默认值为
s
p
r
i
n
g
.
a
p
p
l
i
c
a
t
i
o
n
.
n
a
m
e
,
即
:
服
务
名
D
a
t
a
I
D
中
的
p
r
o
p
e
r
t
i
e
s
:
对
应
客
户
端
的
配
置
s
p
r
i
n
g
.
c
l
o
u
d
.
n
a
c
o
s
.
c
o
n
f
i
g
.
f
i
l
e
−
e
x
t
e
n
s
i
o
n
,
默
认
值
为
p
r
o
p
e
r
t
i
e
s
G
r
o
u
p
的
值
D
E
F
A
U
L
T
G
R
O
U
P
:
对
应
客
户
端
的
配
置
s
p
r
i
n
g
.
c
l
o
u
d
.
n
a
c
o
s
.
c
o
n
f
i
g
.
g
r
o
u
p
,
默
认
值
为
D
E
F
A
U
L
T
G
R
O
U
P
在
采
用
默
认
值
的
应
用
要
加
载
的
配
置
规
则
就
是
:
D
a
t
a
I
D
=
{spring.application.name},即:服务名 Data ID中的properties:对应客户端的配置spring.cloud.nacos.config.file-extension,默认值为properties Group的值DEFAULT_GROUP:对应客户端的配置spring.cloud.nacos.config.group,默认值为DEFAULT_GROUP 在采用默认值的应用要加载的配置规则就是:Data ID=
spring.application.name,即:服务名DataID中的properties:对应客户端的配置spring.cloud.nacos.config.file−extension,默认值为propertiesGroup的值DEFAULTGROUP:对应客户端的配置spring.cloud.nacos.config.group,默认值为DEFAULTGROUP在采用默认值的应用要加载的配置规则就是:DataID={spring.application.name}.properties,Group=DEFAULT_GROUP。
例子一:如果我们不想通过服务名来加载,那么可以增加如下配置,就会加载到Data ID=example.properties,Group=DEFAULT_GROUP的配置内容了:
例子二:如果我们想要加载yaml格式的内容,而不是Properties格式的内容,那么可以通过如下配置,实现加载Data ID=example.yaml,Group=DEFAULT_GROUP的配置内容了:
例子三:如果我们对配置做了分组管理,那么可以通过如下配置,实现加载Data ID=example.yaml,Group=DEV_GROUP的配置内容了:
Nacos的多环境管理
使用Data ID与profiles实现
Data ID在Nacos中,我们可以理解为就是一个Spring Cloud应用的配置文件名。我们知道默认情况下Data ID的名称格式是这样的:
s
p
r
i
n
g
.
a
p
p
l
i
c
a
t
i
o
n
.
n
a
m
e
.
p
r
o
p
e
r
t
i
e
s
,
即
:
以
S
p
r
i
n
g
C
l
o
u
d
应
用
命
名
的
p
r
o
p
e
r
t
i
e
s
文
件
。
实
际
上
,
D
a
t
a
I
D
的
规
则
中
,
还
包
含
了
环
境
逻
辑
,
这
一
点
与
S
p
r
i
n
g
C
l
o
u
d
C
o
n
f
i
g
的
设
计
类
似
。
我
们
在
应
用
启
动
时
,
可
以
通
过
s
p
r
i
n
g
.
p
r
o
f
i
l
e
s
.
a
c
t
i
v
e
来
指
定
具
体
的
环
境
名
称
,
此
时
客
户
端
就
会
把
要
获
取
配
置
的
D
a
t
a
I
D
组
织
为
:
{spring.application.name}.properties,即:以Spring Cloud应用命名的properties文件。 实际上,Data ID的规则中,还包含了环境逻辑,这一点与Spring Cloud Config的设计类似。我们在应用启动时,可以通过spring.profiles.active来指定具体的环境名称,此时客户端就会把要获取配置的Data ID组织为:
spring.application.name.properties,即:以SpringCloud应用命名的properties文件。实际上,DataID的规则中,还包含了环境逻辑,这一点与SpringCloudConfig的设计类似。我们在应用启动时,可以通过spring.profiles.active来指定具体的环境名称,此时客户端就会把要获取配置的DataID组织为:{spring.application.name}-
s
p
r
i
n
g
.
p
r
o
f
i
l
e
s
.
a
c
t
i
v
e
.
p
r
o
p
e
r
t
i
e
s
。
实
际
上
,
更
原
始
且
最
通
用
的
匹
配
规
则
,
是
这
样
的
:
{spring.profiles.active}.properties。 实际上,更原始且最通用的匹配规则,是这样的:
spring.profiles.active.properties。实际上,更原始且最通用的匹配规则,是这样的:{spring.cloud.nacos.config.prefix}-
s
p
r
i
n
g
.
p
r
o
f
i
l
e
.
a
c
t
i
v
e
.
{spring.profile.active}.
spring.profile.active.{spring.cloud.nacos.config.file-extension}。而上面的结果是因为
s
p
r
i
n
g
.
c
l
o
u
d
.
n
a
c
o
s
.
c
o
n
f
i
g
.
p
r
e
f
i
x
和
{spring.cloud.nacos.config.prefix}和
spring.cloud.nacos.config.prefix和{spring.cloud.nacos.config.file-extension}都使用了默认值。
第一步:先在Nacos中,根据这个规则,创建两个不同环境的配置内容。比如:
图片: https://uploader.shimo.im/f/MgKnMm14qu9COY3e.PNG!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDUyMDEzNDgsImciOiJ3VjNWVlhQd1ZwVXBqeTN5IiwiaWF0IjoxNjQ1MjAxMDQ4LCJ1c2VySWQiOjc0OTQ1MzI3fQ.C84lqfv5ZGn3s-zLc4XLOEm_rNWVpekOqFi0oF5yV3s
如上图,我们为alibaba-nacos-config-client应用,定义了DEV和TEST的两个独立的环境配置。我们可以在里面定义不同的内容值,以便后续验证是否真实加载到了正确的配置。
第二步:在alibaba-nacos-config-client应用的配置文件中,增加环境配置:spring.profiles.active=DEV
第三步:启动应用,我们可以看到日志中打印了,加载的配置文件:
2019-01-30 15:25:18.216 INFO 96958 — [ main] o.s.c.a.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: ‘alibaba-nacos-config-client-DEV.properties’, group: ‘DEFAULT_GROUP’
使用Group实现
第一步:先在Nacos中,通过区分Group来创建两个不同环境的配置内容。比如: 图片: https://uploader.shimo.im/f/FXZpsn8xOSFvbsep.PNG!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDUyMDEzNDgsImciOiJ3VjNWVlhQd1ZwVXBqeTN5IiwiaWF0IjoxNjQ1MjAxMDQ4LCJ1c2VySWQiOjc0OTQ1MzI3fQ.C84lqfv5ZGn3s-zLc4XLOEm_rNWVpekOqFi0oF5yV3s
如上图,我们为alibaba-nacos-config-client应用,定义了DEV环境和TEST环境的两个独立的配置,这两个匹配与上一种方法不同,它们的Data ID是完全相同的,只是GROUP不同。
第二步:在alibaba-nacos-config-client应用的配置文件中,增加Group的指定配置:spring.cloud.nacos.config.group=DEV_GROUP
第三步:启动应用,我们可以看到日志中打印了,加载的配置文件:
2019-01-30 15:55:23.718 INFO 3216 — [main] o.s.c.a.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: ‘alibaba-nacos-config-client.properties’, group: ‘DEV_GROUP’
使用Namespace实现
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的Group或Data ID的配置。Namespace的常用场景之一是不同环境的配置的区分隔离,例如:开发测试环境和生产环境的资源(如配置、服务)隔离等。
第一步:先在Nacos中,根据环境名称来创建多个Namespace。比如:
第二步:在配置列表的最上方,可以看到除了Public之外,多了几个刚才创建的Namepsace。分别在DEV和TEST空间下为alibaba-nacos-config-client应用创建配置内容:
https://blog.didispace.com/images/pasted-147.png
第三步:在alibaba-nacos-config-client应用的配置文件中,增加Namespace的指定配置,比如:
https://blog.didispace.com/images/pasted-148.png
spring.cloud.nacos.config.namespace=83eed625-d166-4619-b923-93df2088883a。
这里需要注意namespace的配置不是使用名称,而是使用Namespace的ID。
Nacos配置的多文件加载与共享配置
Nacos配置的多文件加载
Spring应用对Nacos中配置内容的对应关系是通过下面三个参数控制的:
spring.cloud.nacos.config.prefix
spring.cloud.nacos.config.file-extension
spring.cloud.nacos.config.group
默认情况下,会加载Data ID=${spring.application.name}.properties,Group=DEFAULT_GROUP的配置。
假设现在有这样的一个需求:我们想要对所有应用的Actuator模块以及日志输出做统一的配置管理。所以,我们希望可以将Actuator模块的配置放在独立的配置文件actuator.properties文件中,而对于日志输出的配置放在独立的配置文件log.properties文件中。通过拆分这两类配置内容,希望可以做到配置的共享加载与统一管理。
这时候,我们只需要做以下两步,就可以实现这个需求 :
第一步:在Nacos中创建Data ID=actuator.properties,Group=DEFAULT_GROUP和Data ID=log.properties,Group=DEFAULT_GROUP的配置内容。
图片: https://uploader.shimo.im/f/UmwcM4SWIi3LQU8F.PNG!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDUyMDEzNDgsImciOiJ3VjNWVlhQd1ZwVXBqeTN5IiwiaWF0IjoxNjQ1MjAxMDQ4LCJ1c2VySWQiOjc0OTQ1MzI3fQ.C84lqfv5ZGn3s-zLc4XLOEm_rNWVpekOqFi0oF5yV3s
第二步:在Spring Cloud应用中通过使用spring.cloud.nacos.config.ext-config参数来配置要加载的这两个配置内容,比如:
可以看到,spring.cloud.nacos.config.ext-config配置是一个数组List类型。每个配置中包含三个参数:data-id、group,refresh;前两个不做赘述,与Nacos中创建的配置相互对应,refresh参数控制这个配置文件中的内容是否支持自动刷新,默认情况下,只有默认加载的配置才会自动刷新,对于这些扩展的配置加载内容需要配置该设置时候才会实现自动刷新。
共享配置
通过上面加载多个配置的实现,实际上我们已经可以实现不同应用共享配置了。但是Nacos中还提供了另外一个便捷的配置方式,比如下面的设置与上面使用的配置内容是等价的:
spring.cloud.nacos.config.shared-dataids参数用来配置多个共享配置的Data Id,多个的时候用用逗号分隔
spring.cloud.nacos.config.refreshable-dataids参数用来定义哪些共享配置的Data Id在配置变化时,应用中可以动态刷新,多个Data Id之间用逗号隔开。如果没有明确配置,默认情况下所有共享配置都不支持动态刷新
配置加载的优先级
在使用Nacos配置的时候,主要有以下三类配置:
A: 通过spring.cloud.nacos.config.shared-dataids定义的共享配置
B: 通过spring.cloud.nacos.config.ext-config[n]定义的加载配置
C: 通过内部规则(spring.cloud.nacos.config.prefix、spring.cloud.nacos.config.file-extension、spring.cloud.nacos.config.group这几个参数)拼接出来的配置
结论: 后面加载的配置会覆盖之前加载的配置,所以优先级关系是:A < B < C
数据持久化
在搭建Nacos集群之前,我们需要先修改Nacos的数据持久化配置为MySQL存储。默认情况下,Nacos使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的Nacos节点,数据存储是存在一致性问题的。为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只要支持MySQL的存储。
配置Nacos的MySQL存储只需要下面三步:
第一步:安装数据库,版本要求:5.6.5+
第二步:初始化MySQL数据库,数据库初始化文件:nacos-mysql.sql,该文件可以在Nacos程序包下的conf目录下获得。执行完成后可以得到如下图所示的表结构:
图片: https://uploader.shimo.im/f/655GptUm8vp7KZ8G.PNG!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDUyMDEzNDgsImciOiJ3VjNWVlhQd1ZwVXBqeTN5IiwiaWF0IjoxNjQ1MjAxMDQ4LCJ1c2VySWQiOjc0OTQ1MzI3fQ.C84lqfv5ZGn3s-zLc4XLOEm_rNWVpekOqFi0oF5yV3s
第三步:修改conf/application.properties文件,增加支持MySQL数据源配置,添加(目前只支持mysql)数据源的url、用户名和密码。配置样例如下:
集群搭建
MySQL数据源配置
在进行集群配置之前,先完成对MySQL数据源的初始化和配置。主要分以下两步:
第一步:初始化MySQL数据库,数据库初始化文件:nacos-mysql.sql,该文件可以在Nacos程序包下的conf目录下获得。
第二步:修改conf/application.properties文件,增加支持MySQL数据源配置,添加(目前只支持mysql)数据源的url、用户名和密码。配置样例如下:
集群配置
在Nacos的conf目录下有一个cluster.conf.example,可以直接把example扩展名去掉来使用,也可以单独创建一个cluster.conf文件,然后打开将后续要部署的Nacos实例地址配置在这里。
注意:Nacos的集群需要3个或3个以上的节点,并且确保这三个节点之间是可以互相访问的。
启动实例
本地测试
方便地启动Nacos的三个本地实例,我们可以将bin目录下的startup.sh脚本复制三份,分别用来启动三个不同端口的Nacos实例,为了可以方便区分不同实例的启动脚本,我们可以把端口号加入到脚本的命名中,比如:
startup-8841.sh
startup-8842.sh
startup-8843.sh
然后,分别修改这三个脚本中的参数,具体如下图的红色部分(端口号根据上面脚本命名分配): 图片: https://uploader.shimo.im/f/fLbvneUic8ioMGHT.PNG!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDUyMDEzNDgsImciOiJ3VjNWVlhQd1ZwVXBqeTN5IiwiaWF0IjoxNjQ1MjAxMDQ4LCJ1c2VySWQiOjc0OTQ1MzI3fQ.C84lqfv5ZGn3s-zLc4XLOEm_rNWVpekOqFi0oF5yV3s
这里我们通过-Dserver.port的方式,在启动命令中,为Nacos指定具体的端口号,以实现在本机上启动三个不同的Nacos实例来组成集群。
修改完3个脚本配置之后,分别执行下面的命令就可以在本地启动Nacos集群了:
生产环境
在实际生产环境部署的时候,由于每个实例分布在不同的节点上,我们可以直接使用默认的启动脚本(除非要调整一些JVM参数等才需要修改)。只需要在各个节点的Nacos的bin目录下执行sh startup.sh命令即可。
Proxy配置
在Nacos的集群启动完毕之后,根据架构图所示,我们还需要提供一个统一的入口给我们用来维护以及给Spring Cloud应用访问。简单地说,就是我们需要为上面启动的的三个Nacos实例做一个可以为它们实现负载均衡的访问点。这个实现的方式非常多,这里就举个用Nginx来实现的简单例子吧。
在Nginx配置文件的http段中,我们可以加入下面的配置内容:
图片: https://uploader.shimo.im/f/5umQqguiasNAtbst.PNG!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDUyMDEzNDgsImciOiJ3VjNWVlhQd1ZwVXBqeTN5IiwiaWF0IjoxNjQ1MjAxMDQ4LCJ1c2VySWQiOjc0OTQ1MzI3fQ.C84lqfv5ZGn3s-zLc4XLOEm_rNWVpekOqFi0oF5yV3s
这样,当我们访问:http://localhost:8080/nacos/的时候,就会被负载均衡的代理到之前我们启动的三个Nacos实例上了。这里我们没有配置upstream的具体策略,默认会使用线性轮训的方式 。