一、基本要求
1、环境要求:
软件 | 版本要求 |
MySql | 5.6.5以上 64位版本 |
JDK | 1.8以上 |
maven | 3.2以上 |
MySql 5.8(也成为:MySQL 8)下载地址:https://dev.mysql.com/downloads/mysql/
不同的MySQL需要的连接jar包:https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-versions.html
MySQL官网截图:
2、本机环境:
软件 | 版本 |
NACOS | 1.1.4(zip版) |
mysql | mysql 5.7.17-log |
maven | 3.5.4 |
Windows | win10 64bit |
NACOS 1.1.4 Git下载地址:https://github.com/alibaba/nacos
二、安装步骤:
- 从Git上下载后,新建一个名为 nacos 的文件夹,将nacos压缩文件解压到 nacos文件夹中,打开bin目录,
- startup.cmd 命令是 Windows 环境下启动 nacos 的指令 (双击就会执行)
- shutdown.cmd 命令时Windows 环境下启关闭 nacos 的指令 (双击就会执行)
- startup.sh命令是 linux 环境下启动 nacos 的指令 (双击就会执行)
- shutdown.sh命令时 linux 环境下启关闭 nacos 的指令 (双击就会执行)
- 关闭 startup.cmd 命令或 startup.sh命令 的命令窗口时,nacos 服务器也会停止运行,也可以通过shutdown.cmd 命令和shutdown.sh命令关闭 nacos 服务器
- nacos 客户端必须在 nacos 服务端启动后再启动。
三、检验 nacos 是否安装成功
1、DOS命令窗口下的检验(非必要操作,可以跳过,可以直接去搭建数据库)
- 需要安装 curl 工具包
- 点击bin目录下的 startup.cmd 命令运行 nacos服务端
- 使用IP地址 127.0.0.1(localhost):8848/nacos 打开nacos 的管理网页,nacos 的默认端口是:8848,用户名和密码默认都是:nacos
- 在nacos 的 bin 目录下打开dos命令窗口
- 发送配置信息给服务端:执行 curl -X POST “http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.my&group=mygourp&content=helloworld” (这一行语句中间不可以有空格,血的教训),向本地的 Nacos 服务器发送一条配置信息并保存在nacos中,如果按下回车键后,只有弹出true就是成功了,如果弹出其他的都是不对,如下图:
- 客户端从服务端接受配置信息:执行 执行:curl -X GET"http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.my&group=mygourp",如下图,成功接收到了我们刚才发送给服务端的配置信息的contentd的内容:
- 总结:先发送一条配置信息保存在nacos服务端中,然后通过DOS命令窗口模拟客户端根据 dateId 和 group 从服务端接收该配置信息的 content 的值,如果测试通过,则nacos搭建完成
2、配置本地mysql数据库
nacos内嵌了一个数据库,不利用我们观察数据,所以我们使用自己的MySQL数据库,nacos目前只支持MySQL数据库
创建nacos_config数据库步骤
1、在mysql中创建一个名称为nacos_config的数据库:
2、初始化nacos_config数据库:在nacos目录下的conf文件中有一个名为 nacos-mysql.sql的数据库文件,导入到nacso_config数据库中即可。
导入之后,nacos_config数据库中就会生成以下这些表,后面我们在配置中心配置的数据信息都会保存到这些表中,更加利于我们观察:
3、在nacos/conf/application.properties配置文件中增加以下内容:
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root #数据库用户名
db.password=root #数据库密码
3、通过java程序获取配置文件信息
1、nacos 的客户端maven依赖导入:
<!-- https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.1.4</version>
</dependency>
2-1、测试类:
public class Tese {
public static void main(String[] args) throws Exception {
//该参数指定了请求的nacos服务器的IP地址和端口
String serverAddr = "127.0.0.1:8848";
//请求的namespace命名空间Id
String namespace = "90d60786-2b30-4fcd-af4a-74b72559f068";
//请求的dataId
String dataId = "nacos.myconfig";
//请求的group
String group = "mygroup";
//实例化Properties对象
Properties properties = new Properties();
//将请求的IP地址放入到Properties对象,一般建议的把key命名为serverAddr,为了规范
properties.setProperty("serverAddr",serverAddr);
//使用携带ip地址Properties对象获取到 nacos 服务器连接
ConfigService configService = NacosFactory.createConfigService(properties);
/**
* 通过dataId和group获取到content的值,也就是我们最终所需要的配置文件
* 参数一:dataId,参数二:group,参数三:timeout ms
*/
String config = configService.getConfig(dataId, group, 5000);
System.out.println(config);
}
}
2-2、NacosFactory类:
public class NacosFactory {
public NacosFactory() {
}
public static ConfigService createConfigService(Properties properties) throws NacosException {
return ConfigFactory.createConfigService(properties);
}
public static ConfigService createConfigService(String serverAddr) throws NacosException {
return ConfigFactory.createConfigService(serverAddr);
}
public static NamingService createNamingService(String serverAddr) throws NacosException {
return NamingFactory.createNamingService(serverAddr);
}
public static NamingService createNamingService(Properties properties) throws NacosException {
return NamingFactory.createNamingService(properties);
}
public static NamingMaintainService createMaintainService(String serverAddr) throws NacosException {
return NamingMaintainFactory.createMaintainService(serverAddr);
}
public static NamingMaintainService createMaintainService(Properties properties) throws NacosException {
return NamingMaintainFactory.createMaintainService(properties);
}
}
2-3、ConfigFactory类:
public class ConfigFactory {
public ConfigFactory() {
}
public static ConfigService createConfigService(Properties properties) throws NacosException {
try {
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService");
Constructor constructor = driverImplClass.getConstructor(Properties.class);
ConfigService vendorImpl = (ConfigService)constructor.newInstance(properties);
return vendorImpl;
} catch (Throwable var4) {
throw new NacosException(-400, var4);
}
}
public static ConfigService createConfigService(String serverAddr) throws NacosException {
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
return createConfigService(properties);
}
}
NacosFactory.createConfigService()方法是一个重载方法:
static ConfigService createConfigService(Properties properties)
static ConfigService createConfigService(String serverAddr)
只不过管你是传入的是哪个参数,最终执行的都是 createConfigService(Properties properties) 这个方法
关于传参规范问题:
//该参数指定了请求的nacos服务器的IP地址和端口
String serverAddr = "127.0.0.1:8848";
//请求的namespace命名空间Id
String namespace = "90d60786-2b30-4fcd-af4a-74b72559f068";
//实例化Properties对象
Properties properties = new Properties();
/* Properties对象中的key得命名必须规范,否则会导致namespace,获取的数据有误
* 当Properties对象中的不存在 namespace 这个key时,nacos默认启用的是默认命名空间:public
*/
properties.setProperty("serverAddr",serverAddr);
properties.setProperty("namespace",namespace);
Properties对象:
key值 | key值命名不规范是否会导致配置文件读取错误 | 是否严格区分大小写 |
namespace | 是 | 是 |
serverAddr | 否 | 否 |
总结:
- namespace ID 的Key值的命名必须规范化,只能使用 namespace 作为Key值;当我们使用了不规范的key值时,nacos 无法读取到 namespace 的ID,那么nacos就会启用默认命名空间:public 从而导致配置文件读取错误;
- 建议 namespace 和 serverAddr 都使用规范写法,必须使用这两个 key 值,防止出现读取的配置文件错误
四、使用SpringBoot整合Nacos
1、加载单个配置文件:
之所以使用 bootstrap.yml或bootstrap.properties,是因为它会优于application.yml或application.properties之前加载
bootstrap.yml:
server:
port: 8080 #Tomcat启动端口
spring:
application:
name: service1 #项目名称
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 #配置中心地址
file-extension: yaml #文件后缀 ,dataId的名称就是 application.name + file-extension 即从nacos配置中心读取的配置文件为:service1.yaml
namespace: 90d60786-2b30-4fcd-af4a-74b72559f068 # 通过指定namespaceID,选择使用的环境
group: mygroup #group
总结:dataId = application.name + file-extension
bootstrap.properties:
#指定开发环境
spring.profiles.active=dev
#服务器地址
spring.cloud.nacos.config.server-addr=localhost:8848
#默认为Public命名空间,可以省略不写
spring.cloud.nacos.config.namespace=90d60786-2b30-4fcd-af4a-74b72559f068
#指定配置群组 --如果是Public命名空间 则可以省略群组配置
spring.cloud.nacos.config.group=mygroup
#文件名 -- 如果没有配置则默认为 ${spring.appliction.name}
spring.cloud.nacos.config.prefix=service1
#指定文件后缀
spring.cloud.nacos.config.file-extension=yaml
注意:没有指定 namespace 时,默认使用 PUBLIC 命名空间,没有指定 group 时,默认使用 DEAFULTGROUP 组
易错地方:
2、加载多个配置文件
通过自定义 dataId 获取多个配置文件信息
1、加载多配置文件方式一:
server:
port: 8080 #Tomcat启动端口
spring:
application:
name: service1
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 #配置中心地址
file-extension: yaml #文件后缀 ,dataId的名称就是 application.name + file-extension 即从nacos配置中心读取的配置文件为:service1.yaml
namespace: 90d60786-2b30-4fcd-af4a-74b72559f068 # 通过指定namespaceID,选择使用的环境
group: mygroup
ext-config[0]: #没有指定group时,默认使用 DEAFULTGROUP
data-id: common.properties
ext-config[1]:
data-id: common-refresh.properties
group: REFRESH_GROUP #指定group
refresh: true #开启动态刷新,如果不开启,当我们再次更新配置文件内容时,当前客户端的配置信息不会改变
易错点:
ext-config[2]:
namespace: 768dca55-0fcb-47a7-a878-daec27e38909 #这一行会导致报错,初步猜想是由于我们上面已经指定了namespace,所以导致了冲突,或者在配置中无法配置该属性
data-id: nacos.myconfig
group: mygroup
总结:加载多配置文件时,可以重新制定 group ,但是不能重新指定 namespace
2、加载多配置文件方式二(不常用):
server:
port: 8080 #Tomcat启动端口
spring:
application:
name: service1
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 #配置中心地址
file-extension: yaml #文件后缀 ,dataId的名称就是 application.name + file-extension 即从nacos配置中心读取的配置文件为:service1.yaml
namespace: 90d60786-2b30-4fcd-af4a-74b72559f068 # 通过指定namespaceID,选择使用的环境
group: mygroup
shared-dataids: common.properties,common-refresh.properties #多个配置文件之间使用逗号分隔
refreshable-dataids: common.properties,config.properties #开启动态刷新的配置文件,多个配置文件之间使用逗号分隔
注意事项:该方式只会加载在 DEAFULTGROUP 组别中的配置文件,其他组别中的配置文件不会被加载
3、配置文件优先级
Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos拉取配置:
- A:通过 spring.cloud.nacos.config.shared-dataids 支持多个共享 data id 的配置
- A:通过 spring.cloud.nacos.config. ext-config[n].data-id 支持多个扩展 data id 的配置,多个 data id 同时配置时,他的优先级关系是:spring.cloud.nacos.config. ext-config[n].data-id 其中n的值越大,优先级越高
- C:通过内部相关规则(应用名、扩展名 - > application.name + file-extension)自动生成相关的 data Id 的配置
- 当三种方式一起使用时,他们的优先级关系是: C > B > A
六、SpringBoot 整合 Nacos
A、单机NACOS测试
父工程依赖:
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>hp.nacos</groupId>
<artifactId>nacos-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud Begin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Boot Begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
子工程依赖:
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>hp.nacos</groupId>
<artifactId>nacos-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>service1</artifactId>
<packaging>war</packaging>
<name>service1 Maven Webapp</name>
<dependencies>
<!-- 加入nacos客户端依赖,从nacos服务端获取配置文件 -->
<!-- https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
子工程bootstrap.yml:
server:
port: 8080 #Tomcat启动端口
spring:
application:
name: service1
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 #配置中心地址
file-extension: yaml #文件后缀 ,dataId的名称就是 application.name + file-extension 即从nacos配置中心读取的配置文件为:service1.yaml
namespace: f0b22b9a-a433-4c3b-83fc-7b9dd300949d # 通过指定namespaceID,选择使用的环境
group: mygroup
子工程启动类(实现动态配置的第一个方式):
@SpringBootApplication
@RestController
@EnableDiscoveryClient//开启服务发现,暂时没有用到
@RefreshScope//nacos配置文件中的配置信息自动更新,让@value注解修饰的属性信息动态注入
public class MyClass {
public static void main(String[] args) {
SpringApplication.run(MyClass.class,args);
}
@Value("${name}")
private String name;
@GetMapping("/index")
public String index(){
return name;
}
}
注解使用:
@EnableDiscoveryClient 能够让注册中心能够发现,扫描到改服务。若没有该注解,该服务将不会被Nacos所发现。
@RefreshScope 配置文件自动刷新,我们可以通过Nacos配置中心去修改该服务的配置文件,如果不添加该注解,那么客户端获取的配置信息不会随着服务端的配置中心的配置信息的改变而改变,@Value + @RefreshScope就能实现配置文件动态获取
子工程启动类(实现动态配置的第二个方式):
@SpringBootApplication
@RestController
public class MyClass {
public static void main(String[] args) {
SpringApplication.run(MyClass.class,args);
}
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping("/config")
public String config(){
String name = applicationContext.getEnvironment().getProperty("name");
String cName = applicationContext.getEnvironment().getProperty("common.name");
String cAge = applicationContext.getEnvironment().getProperty("common.age");
String cAddress = applicationContext.getEnvironment().getProperty("common.address");
String myname = applicationContext.getEnvironment().getProperty("myname");
StringBuilder sb = new StringBuilder(name);
sb.append("-"+cName);
sb.append("-"+cAge);
sb.append("-"+cAddress);
sb.append("-"+myname);
return sb.toString();
}
}
单独使用@Value获取配置信息时,只会加载一次(初始化),当Nacos服务端的配置信息发生变动,那么@Value的值还是初始化时的值,
1、nacos集群必须包含3个以上的 Nacos 节点
将已经解压的 Nacos 文件夹复制多个,分别将文件夹名称改为nacos、nacos1、nacos2
2、配置集群配置文件
1、 依次修改每个 nacos 的端口和ip地址
nacos 配置文件路径:nacos\conf\application.properties
nacos下application.properties修改的部分:
端口不要重复,否则会导致冲突
nacos的配置文件:
server.port=8848
nacos.inetutils.ip-address=127.0.0.1 #指定ip,我这里是本机,所以可以使用 127.0.0.1 或 localhost,如果不指定该参数,会导致节点不会生效,nacos的控制台上看不到集群的节点信息
nacos1的配置文件:
server.port=8849
nacos.inetutils.ip-address=127.0.0.1
nacos2的配置文件:
server.port=8850
nacos.inetutils.ip-address=127.0.0.1
集群节点图:
如果无法出现上面的节点显示,就去每个Nacos节点检查 nacos/conf/application.properties 中是否指定了 nacos.inetutils.ip-address 的IP值
2、将所有 Nacos 目录的conf目录下的 cluster.conf.example 文件更名为 cluster.conf 并为其配置每个 ip 对应的节点
cluster.conf.example:集群模板,只有将名称改为 cluster.conf 后,该配置文件才会生效
cluster.conf:
#ip:port
#ip:我们在第一步指定的ip
#port:与该ip对应的端口
# 127.0.0.1:8848 所对应的就是 nacos
# 127.0.0.1:8849 所对应的就是 nacos1
# 127.0.0.1:8850 所对应的就是 nacos2
127.0.0.1:8848
127.0.0.1:8849
127.0.0.1:8850
作用:这样就形成了集群化,被指定的 nacos 都加入到集群中来了
3、启动集群
1、启动
不能直接点击 stratup.cmd 启动
依次进入到每个nacos文件的bin目录下,直接打开 CMD命令行控制输入:startup.cmd -m cluster 即可
2、检验是否启动了集群
访问任意一台nacos的控制台,点击节点列表,可以看到:
nacos.inetutils.ip-address 的IP值**
2、将所有 Nacos 目录的conf目录下的 cluster.conf.example 文件更名为 cluster.conf 并为其配置每个 ip 对应的节点
cluster.conf.example:集群模板,只有将名称改为 cluster.conf 后,该配置文件才会生效
cluster.conf:
#ip:port
#ip:我们在第一步指定的ip
#port:与该ip对应的端口
# 127.0.0.1:8848 所对应的就是 nacos
# 127.0.0.1:8849 所对应的就是 nacos1
# 127.0.0.1:8850 所对应的就是 nacos2
127.0.0.1:8848
127.0.0.1:8849
127.0.0.1:8850
作用:这样就形成了集群化,被指定的 nacos 都加入到集群中来了
3、启动集群
1、启动
不能直接点击 stratup.cmd 启动
依次进入到每个nacos文件的bin目录下,直接打开 CMD命令行控制输入:startup.cmd -m cluster 即可
2、检验是否启动了集群
访问任意一台nacos的控制台,点击节点列表,可以看到: