SpringCloud Alibaba系列——1Nacos
作者 | 宇木木兮
来源 |今日头条
学习目标
- nacos是什么
- nacos的作用
- nacos-server部署
- nacos集成springboot
- nacos集成springcloud
- nacos常用api的使用
nacos集群部署
第1章 概述
官网:
https://nacos.io/zh-cn/index.html
1.1 Nacos是什么
一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
上面这段话就是官网给的解释,实际上说白了,Nacos就是一个做注册中心的和配置中心的。
1.2 Nacos架构
Nacos的整体架构还是比较清晰的,我们可以从下面这个官方提供的架构图进行简单分析。事实上Nacos就是一个springboot的web项目,它提供了注册和配置的相关核心功能,然后对外暴露了各种接口;我相信做过javaweb开发的同学都知道,怎么对外提供接口呢?无非就是通过controller层暴露一些RequestMapping嘛,这点,咱们可以通过源码去验证。
nacos具体暴露哪些接口调用可以参考:
https://nacos.io/zh-cn/docs/open-api.html。
到这一步,我们大概明白了nacos的架构了,但是有一个问题,虽然nacos提供了各种接口,但是我们要使用它的话,不能我们自己去封装各种http调用工具去调用它的接口吧?如果是要我们自己通过业务代码去封装工具的话,那nacos的价值也不会很高,所以,为了让我们使用起来更加方便,nacos的设计者肯定是要帮我们做一些事情的,这个时候nacos就分为了两个模块:nacos-server(主要提供注册和配置的核心功能)和nacos-client端(这里面实际上就是封装了http调用的一些工具,让使用者不需要自己去封装,只要调用方法就好了)。
nacos-client封装了哪些方法可以参考:
https://nacos.io/zh-cn/docs/sdk.html。
到这一步,事实上还是不够,我们一起来想想,虽然nacos-client端给我们封装了工具,但是我业务代码还是得去手动调用这些方法,还是对我的业务代码有侵入性,这样的话还是不够简洁。这个时候怎么办呢?我们会想到springboot的自动装配,通过springboot去帮我们完成对象的实例化,然后在适当的时机自动帮我们调用核心api。
这个时候好事之人帮我们对nacos-client包又进行了封装,有注册的jar包:
nacos-discovery-spring-boot-starter和配置的jar包:nacos-config-spring-boot-starter,但是事实上这两个jar包功能还不够强大,因为无法做到自动注册,而且动态刷新配置的时候需要加一些注解,那好事之人又出现了,对nacos-client做了更进一步封装:spring-cloud-starter-alibaba-nacos-discovery和spring-cloud-starter-alibaba-nacos-config。后面会具体介绍如何使用。
第2章 Nacos应用
2.1 Nacos-server启动
我们需要先启动Nacos服务,启动服务有两种方式,一种是直接下载已经编译好的包直接运行。另一种是通过源码来构建的。
2.1.1 直接启动
下载地址:
https://github.com/alibaba/nacos/releases?page=3
上传到服务器 cd /usr/local/eclipse2019
解压:tar -zxvf nacos-server-1.4.2.tar.gz
进入
/usr/local/eclipse2019/nacos/bin目录下执行./startup.sh -m standalone或sh startup.sh -m standalone 命令启动单机模式nacos
关闭firewall:systemctl stop firewalld.service
禁止firewall开机启动:systemctl disable firewalld.service
nacos设置开机自启动
1.添加nacos.service文件
vim /lib/systemd/system/nacos.service
[Unit]
Description=nacos
After=network.target
[Service]
Type=forking
Environment=“JAVA_HOME=/usr/local/eclipse2019/java"
ExecStart=/usr/local/eclipse2019/nacos/bin/startup.sh -m standalone
ExecReload=/usr/local/eclipse2019/nacos/bin/shutdown.sh
ExecStop=/usr/local/eclipse2019/nacos/bin/shutdown.sh
PrivateTmp=true
[Install]
WantedBy=multi-user.target
2.加入nacos服务
systemctl daemon-reload
3.设置开机自启
systemctl enable nacos.service
4.查看该service是否开机启用
systemctl is-enabled nacos.service
5.启动nacos服务和关闭服务
systemctl start nacos.service
systemctl stop nacos.service
6.查看该服务状态
systemctl status nacos.service
如果开启自启报which: no javac in (
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)错误,解决方案:
vim /usr/local/eclipse2019/nacos/bin/startup.sh
JAVA_HOME=/usr/local/eclipse2019/java
2.1.2 docker启动
Nacos也可以直接通过docker安装。
docker run -d --name nacos-server-8848 -p 8848:8848 --privileged=true --network=host -v /opt/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties -v /opt/nacos/logs:/home/nacos/logs --restart=always -e MODE=standalone -e PREFER_HOST_MODE=hostname nacos/nacos-server:1.1.0
开放8848端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload #重启firewall
2.1.3 基于源码构建
1)从GitHub上下载源码
git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos clean install -U
ls -al distribution/target/
cd distribution/target/nacos-server-$version/nacos/bin
2)启动服务
linux系统下: sh startup.sh -m standalone
window系统: cmd startup.cmd
3)如果是源码启动
下载源码到本地,然后通过ideal打开:如果编译nacos源码失败
com.alibaba.nacos.consistency.entity
- 下载https://github.com/protocolbuffers/protobuf/releases/tag/v3.16.0
- 在Path中添加D:\Program Files\protoc-3.16.0-win64\bin
- 进入到源码的这个consistency/src/main/proto/路径下,使用cmd命令,运行如下指令
protoc --java_out=../java/ ./consistency.proto
protoc --java_out=../java/ ./Data.proto
命令执行完,就能编译成功了
进入到console包下修改配置文件application.properties
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://192.168.8.74:3306/nacos-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456
添加启动配置2.1.4 访问nacos
http://localhost:8848/nacos
默认的帐号密码是:nacos/nacos
2.2 Nacos-client应用
2.2.1 集成springboot
2.2.1.1 动态配置
官方提供代码案例见
nacos-spring-boot-example/nacos-spring-boot-config-example
下面我们自己实现一下
1.创建spring boot应用
2.添加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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-eclipse2019-nacos-config</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-eclipse2019-nacos-config</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>0.2.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.创建一个controller作为测试
@RestController
@NacosPropertySource(dataId = "example-dev.properties",autoRefreshed = true)
public class TestController {
@NacosValue(value="${eclipse2019:woman}",autoRefreshed = true)
private String eclipse2019;
@GetMapping("/get")
public String get(){
return "eclipse2019是个"+eclipse2019;
}
}
4.修改application.properties文件
nacos.config.server-addr=192.168.8.74:8848
2.2.1.2 注册中心
官方提供代码案例见
nacos-spring-boot-example/nacos-spring-boot-discovery-example
springboot集成nacos自身没有提供自动注册的api,需要手动实现
1.简单注册实现
- 添加jar包依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-eclipse2019-nacos-discovery</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-eclipse2019-nacos-discovery</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>0.2.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 创建一个测试类,用户返回当前nacos服务器上注册的服务列表
@RestController
public class ServiceController {
@NacosInjected
private NamingService namingService;
@GetMapping("/discovery")
public List<Instance> get(@RequestParam String serviceName) throws NacosException {
return namingService.getAllInstances(serviceName);
}
@PostMapping("/registry")
public void registry(@RequestBody RegistryInstance registryInstance) throws NacosException {
namingService.registerInstance(registryInstance.getSeriveName(),registryInstance.getIp(),
registryInstance.getPort(),registryInstance.getGroupName());
}
}
- 修改application.properties文件
nacos.discovery.server-addr=192.168.8.74:8848
- 先调用registry这个接口,向nacos注册服务
- 再访问 http://localhost:8080/discovery?serviceName=example 获取指定服务的实例信息
- 也可以通过直接调用nacos server的服务注册接口进行服务注册
2.自动注册实现http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=example&ip=127.0.0.1&port=8080
- pom文件中增加
<dependency> <groupId>com.alibaba.boot</groupId> <artifactId>nacos-config-spring-boot-starter</artifactId> <version>0.2.7</version> </dependency>
- application.properties中添加以下配置
# springApplicationName spring.application.name=nacos-server # 应用端口以及地址 server.port=8088 server.ip=192.168.8.20 # nacos配置中心地址 nacos.config.server-addr=192.168.8.74:8848
- 然后在项目中增加配置类
@Configuration @NacosPropertySource(dataId = "springboot-eclipse2019-nacos-discovery",autoRefreshed = true) public class NacosConfig { @Value("${server.port}") private int serverPort; @Value("${server.ip}") private String ip; @Value("${spring.application.name}") private String applicationName; @NacosInjected private NamingService namingService; /** * 开机自动注册服务 * * @throws NacosException */ @PostConstruct public void registerInstance() throws NacosException { namingService.registerInstance(applicationName, ip, serverPort); } }
这种方式不够友好,会存在bean实例化的时候去注册服务,但是此时服务并不一定百分百启动成功。所以自动注册还可以通过下面这种方式
- 通过事件监听的方式实现自动注册
@Component public class AutoReigsterDemo implements ApplicationListener { @Value("${server.port}") private int serverPort; @Value("${server.ip}") private String ip; @Value("${spring.application.name}") private String applicationName; @NacosInjected private NamingService namingService; @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { try { namingService.registerInstance(applicationName, ip, serverPort); } catch (NacosException e) { e.printStackTrace(); } } }
2.2.2 集成springcloud
2.2.2.1 注册中心
接下来,我们通过一个案例来演示一下spring cloud alibaba下使用nacos实现配置中心以及服务注册的功能。
官方代码见
nacos-examples-master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example
下面我们自己实现一下
1.maven父工程
springcloud-eclipse2019-nacos-discovery
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
<spring-boot.version>2.2.5.RELEASE</spring-boot.version>
</properties>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>springcloud-eclipse2019-nacos-discovery</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>nacos-api</module>
<module>nacos-provider</module>
<module>nacos-consumer</module>
</modules>
<dependencyManagement>
<dependencies>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
2.接口端
创建maven的quickstart项目,nacos-api
- pom文件替换
<parent> <groupId>com.example</groupId> <artifactId>springcloud-eclipse2019-nacos-discovery</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>nacos-api</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-openfeign-core</artifactId> <version>2.0.0.RELEASE</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> <plugin> <artifactId>maven-site-plugin</artifactId> <version>3.7.1</version> </plugin> <plugin> <artifactId>maven-project-info-reports-plugin</artifactId> <version>3.0.0</version> </plugin> </plugins> </pluginManagement> </build>
- 创建接口UserService
public interface UserService {
@GetMapping("/users")
String users();
@PostMapping("/user")
String insert(@RequestBody UserDto userDto);
}
- 创建UserDto
public class UserDto { private String name; private String sex; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
- 创建UserServiceClient
3.服务提供端@FeignClient("nacos-provider")//这里要跟服务提供端注册的名字一样 public interface UserServiceClient extends UserService { }
创建springboot项目nacos-provider
- 替换pom
<parent> <groupId>com.example</groupId> <artifactId>springcloud-eclipse2019-nacos-discovery</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>nacos-provider</artifactId> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>nacos-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
- 创建接口实现类
@RestController public class UserServiceImpl implements UserService { @Value("${server.port}") private int port; @Override public String users() { return "获取"+port+"端口上的user成功"; } @Override public String insert(UserDto userDto) { return port+"端口上:"+userDto.getName()+","+ userDto.getAge()+","+userDto.getSex()+"插入成功"; } }
- 启动类增加注解
@SpringBootApplication @EnableDiscoveryClient public class NacosProviderApplication { public static void main(String[] args) { SpringApplication.run(NacosProviderApplication.class, args); } }
- 配置文件
4.服务消费端spring.application.name=nacos-provider server.port=8088 spring.cloud.nacos.discovery.server-addr=192.168.8.74:8848 # 注册到 nacos 的指定 namespace,默认为 public #spring.cloud.nacos.discovery.namespace=dbaf147f-cf53-4d0b-8b17-d4313c17beb9
- 创建springboot项目nacos-consumer
替换pom
<parent>
<groupId>com.example</groupId>
<artifactId>springcloud-eclipse2019-nacos-discovery</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos-consumer</artifactId>
<properties>
<spring-cloud-openfeign.version>2.0.0.RELEASE</spring-cloud-openfeign.version>
<spring-cloud-netflix.version>2.0.0.RELEASE</spring-cloud-netflix.version>
</properties>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>nacos-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>${spring-cloud-netflix.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${spring-cloud-openfeign.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
- 创建controller
@RestController public class TestController { @Autowired UserServiceClient userServiceClient; @GetMapping("/user") public String users(){ int a = 0; return userServiceClient.users(); } @PostMapping("/user") public String user(@RequestBody UserDto userDto){ return userServiceClient.insert(userDto); } }
- 启动类增加注解
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients(basePackages = "com.example.clients")//这里的地址要跟api中的client地址一样 public class NacosConsumerApplication { public static void main(String[] args) { SpringApplication.run(NacosConsumerApplication.class, args); } }
- 配置文件
2.2.2.2 配置中心spring.application.name=nacos-consumer server.port=8080 spring.cloud.nacos.discovery.server-addr=192.168.8.74:8848
在Nacos中,实现动态配置管理,相对于Spring Cloud中的Config来说,友好太多了,先给大家简单演示一下
代码见
nacos-examples-master/nacos-spring-cloud-example/nacos-spring-cloud-config-example
下面我们自己实现一下
springcloud-eclipse2019-nacos-config
1.配置pom
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springcloud-eclipse2019-nacos-config</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-eclipse2019-nacos-config</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
</dependencies>
2.bootstrap.properties
spring.cloud.nacos.config.server-addr=192.168.8.74:8848
spring.application.name=nacos-config
需要注意,配置中心的ip,需要放在bootstrap.properties文件中,因为需要保证优先级。
3.TestController
@RestController
@RequestMapping("/config")
@RefreshScope
public class TestController {
@Value("${eclipse2019:girl}")
private String eclipse2019;
@RequestMapping("/get")
public String get(){
return eclipse2019;
}
}
4.测试过程
- 启动服务,访问http://localhost:8080/config/get,浏览器会显示eclipse2019的默认值,因为这个时候nacos还没有配置eclipse2019的key
- 进入控制台,增加配置,dataid=nacos-config.properties,group=default_group, 并且增加 eclipse2019= xx的value属性 再次刷新url,就可以读取到值的变化
5.关于Nacos Config配置解释
在 Nacos Spring Cloud 中, dataId 的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
- prefix 默认为 spring.application.name 的值,也可以通过配置项spring.cloud.nacos.config.prefix 来配置。
- spring.profiles.active 即为当前环境对应的 profile,详情可以参考 。 注意:当spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成${prefix}.${file-extension}
- file-exetension 为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
2.3 Nacos的集群搭建
在前面的课程讲解过程中,我们部署的Nacos是一个standalone的模式。Nacos是可以支持集群部署的,我们可以配置三台服务器做一个简单的测试
2.3.1 环境准备
准备三台服务器
- 192.168.8.74
- 192.168.8.75
- 192.168.8.76
2.3.2 下载编译好的包
https://github.com/alibaba/nacos/releases/download/1.3.2/nacos-server-1.3.2.tar.gz
2.3.3 配置数据源
需要注意的是,Nacos默认采用的是一个derby的内置数据库,在实际过程中,不建议使用这种数据源。建议采用高可用数据库,比如我们使用mysql构建主从。
那我们可以使用mysql作为数据源来进行服务的配置。
1.导入mysql数据库脚本
每台nacos服务都连各自的数据库
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info */
/******************************************/
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) DEFAULT NULL,
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`c_desc` varchar(256) DEFAULT NULL,
`c_use` varchar(64) DEFAULT NULL,
`effect` varchar(64) DEFAULT NULL,
`type` varchar(64) DEFAULT NULL,
`c_schema` text,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_aggr */
/******************************************/
CREATE TABLE `config_info_aggr` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) NOT NULL COMMENT 'group_id',
`datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
`content` longtext NOT NULL COMMENT '内容',
`gmt_modified` datetime NOT NULL COMMENT '修改时间',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_beta */
/******************************************/
CREATE TABLE `config_info_beta` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_info_tag */
/******************************************/
CREATE TABLE `config_info_tag` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = config_tags_relation */
/******************************************/
CREATE TABLE `config_tags_relation` (
`id` bigint(20) NOT NULL COMMENT 'id',
`tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
`tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = group_capacity */
/******************************************/
CREATE TABLE `group_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = his_config_info */
/******************************************/
CREATE TABLE `his_config_info` (
`id` bigint(64) unsigned NOT NULL,
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`data_id` varchar(255) NOT NULL,
`group_id` varchar(128) NOT NULL,
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL,
`md5` varchar(32) DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`src_user` text,
`src_ip` varchar(50) DEFAULT NULL,
`op_type` char(10) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';
/******************************************/
/* 数据库全名 = nacos_config */
/* 表名称 = tenant_capacity */
/******************************************/
CREATE TABLE `tenant_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';
CREATE TABLE `tenant_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`kp` varchar(128) NOT NULL COMMENT 'kp',
`tenant_id` varchar(128) default '' COMMENT 'tenant_id',
`tenant_name` varchar(128) default '' COMMENT 'tenant_name',
`tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
`create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
`gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
`gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
CREATE TABLE `users` (
`username` varchar(50) NOT NULL PRIMARY KEY,
`password` varchar(500) NOT NULL,
`enabled` boolean NOT NULL
);
CREATE TABLE `roles` (
`username` varchar(50) NOT NULL,
`role` varchar(50) NOT NULL,
UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);
CREATE TABLE `permissions` (
`role` varchar(50) NOT NULL,
`resource` varchar(255) NOT NULL,
`action` varchar(8) NOT NULL,
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
2.修改nacos中application.properties文件内容
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
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?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=nacos
db.password=nacos
2.3.4 启动nacos服务
启动nacos服务之前,需要配置集群
在nacos/conf目录下,有一个cluster.conf配置文件,在这个配置文件中配置这三个节点的ip和端口
192.168.8.74:8848
192.168.8.75:8848
192.168.8.76:8848
三种不同启动方式命令
外部数据源
#我们使用的外部数据源,所以用这个命令启动,三台服务器都需要启动
sh startup.sh
内存数据源
sh startup.sh -p embedded
当然,Nacos也可以支持单机运行
sh startup.sh -m standalone
2.4 Nacos server监控
2.4.1 Prometheus
Prometheus是一个开源的监控系统,起源于SoundCloud。它由以下几个核心组件构成:
- 数据爬虫:根据配置的时间定期的通过HTTP抓去metrics数据。
- time-series 数据库:存储所有的metrics数据。
- 简单的用户交互接口:可视化、查询和监控所有的metrics。
2.4.2 Grafana
Grafana使你能够把来自不同数据源比如Elasticsearch, Prometheus, Graphite, influxDB等多样的数据以绚丽的图标展示出来。
它也能基于你的metrics数据发出告警。当一个告警状态改变时,它能通知你通过email,slack或者其他途径。
值得注意的是,Prometheus仪表盘也有简单的图标。但是Grafana的图表表现的更好。这也是为什么,我们需要整合Grafana和Pormetheus来可视化metrics数据。
2.4.3 Nacos server接入到监控
- 修改${NACOS_HOME}/conf/application.properties
- 访问这个地址: http://192.168.216.128:8848/nacos/actuator/prometheus 可以看到服务监控信息
修改prometheus.yml,添加Nacos的采集任务
修改prometheus.yml
- job_name: 'nacos'
metrics_path: '/nacos/actuator/prometheus'
static_configs:
- targets:
["192.168.216.128:8848","192.168.216.129:8848","192.168.216.130:8848"]
- job_name:任务名称
metrics_path: 指标路径
targets:实例地址/项目地址,可配置多个
scrape_interval: 多久采集一次
scrape_timeout: 采集超时时间
- 启动prometheus服务
./prometheus --config.file="prometheus.yml" [root@localhost prometheus-2.17.1.linux-amd64]# nohup ./prometheus --config.file=prometheus.yml --web.enable-lifecycle > prometheus.log 2>&1 &
- 访问:http://192.168.216.128:9090/
在搜索栏中搜索 nacos_monitor,如果可以看到nacos的数据,说明采集成功
在status菜单的service discovery中,可以看到nacos这个job
2.4.4 采用grafana图形化展示metrics数据
下载Grafana:https://grafana.com/grafana/download
wget https://dl.grafana.com/oss/release/grafana-7.0.3-1.x86_64.rpm
sudo yum install grafana-7.0.3-1.x86_64.rpm
- 启动Grafana, service grafana-server start / $GRAFANA_HOME/bin/grafana-server
- 访问Grafana , http://localhost:3000 , 默认的帐号密码 admin/admin
- 菜单选择 Configuration -> Data Source -> Add Data Source -> 名字:prometheus
- 导入nacos的面板数据 .nacos-granfa.json