Nacos 官网地址:https://nacos.io
我们先进入它的官网看看,官网说的很清楚了Nacos
的2个核心能力:
所以Nacos可以作为:
其他:
Nacos支持AP和CP模式的切换
C是所有节点在同一时间看到的数据是一致的;而A的定义是所有的请求都会收到响应。
何时选择使用何种模式?
—般来说,如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如Spring cloud和Dubbo服务,都适用于AP模式,AP模式为了服务的可能性而减弱了一致性,因此AP模式下只支持注册临时实例。
如果需要在服务级别编辑或者存储配置信息,那么CP是必须,K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。
切换命令:
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP
下载地址: 最新稳定版本 下载nacos-server-$version.zip
# 进入nacos下的bin目录
cd nacos/bin
而Nacos
支持三种服务部署方式
这里就使用单机模式了
启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:
bash startup.sh -m standalone
启动命令(standalone代表着单机模式运行,非集群模式):
startup.cmd -m standalone
双击 startup.cmd 文件也行
浏览器访问 127.0.0.1:8848 就能看到Nacos的Web页面了,默认的账号密码都是 nacos
新建module:nacos-provider
pom.xml文件如下(注意spring-boot-starter-web
也一定要引入,因为有被使用):
<?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.apps</groupId>
<artifactId>nacos-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>nacos-provider</name>
<properties>
<java.version>1.8</java.version>
<nacos.version>2.2.6.RELEASE</nacos.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Web启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Nacos依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml文件如下:
server:
port: 7001
spring:
application:
# 微服务名称
name: service-provider
cloud:
nacos:
discovery:
# nacos服务发现地址, 多个地址使用逗号隔开, 注意: 不用添加http(s)://
server-addr: 192.168.6.206:8848
主启动类:
(@EnableDiscoveryClient) SpringCloud的服务注册发现标签,让注册中心能够发现,扫描到该服务
package com.apps;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class NacosDemoApplication {
public static void main(String[] args) {
SpringApplication.run(NacosDemoApplication.class, args);
}
}
编写控制器:
package com.apps.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Blue 2113438464@qq.com
* @ClassName ProviderController
* @Description 作用
* @date 2022/6/13 9:49
* @Version 1.0
*/
@RestController
@RequestMapping("/provider")
public class ProviderController {
@Value("${server.port}")
private String port;
@GetMapping("/info")
public String getPayment(){
return "nacos注册表,服务器端口:" + port ;
}
}
然后启动该模块,在nacos控制台就能看到该实例已经注册到nacos:
新建module:nacos-consumer
pom.xml文件如下(注意spring-boot-starter-web
也一定要引入,因为有被使用):
<?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.apps</groupId>
<artifactId>nacos-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>nacos-consumer</name>
<properties>
<java.version>1.8</java.version>
<nacos.version>2.2.6.RELEASE</nacos.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Web启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Nacos依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${nacos.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
</plugins>
</build>
</project>
application.yml文件如下:
server:
port: 10083
spring:
application:
name: service-consumer
cloud:
nacos:
discovery:
server-addr: 192.168.6.206:8848
# 消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
nacos-user-service: http://service-provider
主启动类:
package com.apps;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConsumerApplication.class, args);
}
}
配置类:
package com.apps.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
/**
* @author Blue 2113438464@qq.com
* @ClassName JavaConfig
* @Description 作用
* @date 2022/6/13 10:50
* @Version 1.0
*/
@Component
public class JavaConfig {
// @LoadBalanced这个注解是让 RestTemplate 开启负载均衡的能力
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
控制器:
package com.apps.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @author Blue 2113438464@qq.com
* @ClassName controller
* @Description 作用
* @date 2022/6/13 10:56
* @Version 1.0
*/
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Value("${service-url.nacos-user-service}")
private String serviceUrl;
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "/info")
public String getClientServerResult(){
return restTemplate.getForObject(serviceUrl + "/provider/info", String.class);
}
}
然后启动消费者模块,在nacos控制台可以看到服务列表
然后启动消费者模块,在nacos控制台可以看到服务列表,便可以使用服务了,当前我们可以启动多个服务名相同服务实例来使用Nacos的负载均衡。
nacos支持负载均衡是因为spring-cloud-starter-alibaba-nacos-discovery内含netflix-ribbon包(这里要感谢技术大牛浩哥
的指导)。
为了省事,我们可以直接copy一个provider进行启动
修改名字,好区别。并且指定服务端口,这里指定权重更高,所以优先VM的参数
copy完成后,启动。就有两个相同服务名的实例了
然后通过consumer的AIP访问provider的接口,通过打印可以知道是轮询访问10001/10002
新建module:nacos-config
pom.xml文件如下(注意这里引入的是spring-cloud-starter-alibaba-nacos-config
):
<?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.apps</groupId>
<artifactId>nacos-config</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>nacos-config</name>
<description>nacos-config</description>
<properties>
<java.version>1.8</java.version>
<nacos.version>2.2.6.RELEASE</nacos.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--nacos-config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>${nacos.version}</version>
</dependency>
<!-- Web启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
nacos和springcloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。
springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application。所以我们拉取配置需要写在bootstrap.yml文件中,启动完bootstrap.yml把相关配置拉取下来后才能正常启动项目。
配置bootstrap.yml文件
server:
port: 3377
spring:
application:
name: nacos-config
cloud:
nacos:
config:
server-addr: 192.168.6.206:8848 # nacos本地服务器地址
file-extension: yaml # 配置文件的格式,默认properties
group: DEFAULT_GROUP # 分组,默认DEFAULT_GROUP
配置application.yml文件
spring:
profiles:
active: dev
前面我们在bootstrap.yml文件中配置了spring.application.name
,是因为它是构成 Nacos 配置管理 dataId
字段的一部分(是什么dataId等一些技术名词我会在文章后面讲解)。
在Nacos Spring Cloud 中,dataId
的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
prefix
默认为 spring.application.name
的值,也可以通过配置项 spring.cloud.nacos.config.prefix
来配置。spring.profiles.active
即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profiles.active
为空时,对应的连接符 -
也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
file-exetension
为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension
来配置。目前只支持 properties
和 yaml
类型。最后公式:
${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
接下来在nacos控制台新增配置
保存后,创建控制器
package com.apps.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Blue 2113438464@qq.com
* @ClassName NacosConfigController
* @Description 作用
* @date 2022/6/13 16:58
* @Version 1.0
*/
@RefreshScope
@RestController
public class NacosConfigController {
@Value("${user.name}")
private String name;
@Value("${user.age}")
private String name;
@RequestMapping(value = "config/info")
public String getConfigValue() {
System.err.println("user name :" +name+"; age: "+age);
return this.name + this.age;
}
}
启动项目,访问请求,控制台打印
nacos控制台修改yml参数后(也可以发送Open API修改),又访问请求,配置信息就修改了。
三个东西是为了解多项目多环境的问题。
实际开发中,通常一个系统会准备
如何保证指定环境启动时服务能正确读取到Nacos上相应环境的配置文件呢?
一个大型分布式微服务系统会有很多微服务子项目,每个微服务项目又都会有相应的开发环境、测试环境、预发环境、正式环境…那怎么对这些微服务配置进行管理呢?
nacos默认的namespace是public,默认的group是DEFAULT_GROUP
类似Java里面的package名和类名,最外层的namespace是可以用于区分部署环境的,Group和DatalD逻辑上区分两个目标对象。
比方说我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的Namespace之间是隔离的。
我们可以在nacos控制台创建namespace和group。
创建dev和test的namespace
回到配置列表,就能看到我们创建的namespace
分别在test和dev的namespace里新建配置文件
在bootstrap.yml中指定group和namespace就可以获取不同的配置文件了。(记住dataId的生成规则)
spring:
application:
name: cloud-nacos-config
cloud:
nacos:
config:
server-addr: localhost:8848 # nacos本地服务器地址
file-extension: yaml # 配置文件的格式,默认properties
group: TEST_GROUP # 分组,默认DEFAULT_GROUP
# group: DEV_GROUP
namespace: 155a7fd7-6834-4787-80f7-35f56dd9f8fb
# namespace: 2f42a525-6d50-45dc-8ed1-d474fff7ce42
对于Nacos配置管理,通过Namespace、group、Data ID能够定位到一个配置集
配置集(Data ID)
在系统中,一个配置文件通常就是一个配置集,一个配置集可以包含了系统的各种配置信息,例如一个配置集可能包含了数据源、线程池、日志级别等配置项。每个配置集都可以定义一个有意义的名称,就是配置集的ID即Data ID
配置项
就是我们的配置内容
配置集中包含的一个个配置内容就是配置项。它代表一个具体的可配置的参数与其值域,通常以key=value的形式存在。例如我们常配置系统的日志输出级别( logLevel=INFO |WARN|ERROR)就是一个配置项
配置分组(Group)
配置分组是对配置集进行分组,通过一个有意义的字符串(如Buy或Trade ) 来表示
不同的配置分组下可以有相同的配置集( DataID)。当您在Nacos上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用DEFAULT_GROUP。配置分组的常见场景:可用于区分不同的项目或应用,例如学生管理系统的配置集可以定义一个group为:STUDENT_GROUP
命名空间(Namespace)
命名空间( namespace )可用于进行不同环境的配置隔离
例如可以隔离开发环境、测试环境和生产环境,因为它们的配置可能各不相同,或者是隔离不同的用户,不同的开发人员使用同一个nacos管理各自的配置,可通过namespace隔离。
不同的命名空间下,可以存在相同名称的配置分组(Group)或配置集。
获取某配置集的代码:需要指定
如果您对本文有任何疑问或需要帮助,请在评论区留言,我会尽力解答。如果本文对您有帮助,请给个赞以示支持,非常感谢!💗
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。