一、nacos的基本概念
nacos的服务模型如下:
Nacos 服务发现使用的领域模型是命名空间-分组-服务-集群-实例这样的多层结构,服务 Service 和实例 Instance 是核心模型,命名空间 Namespace 、分组 Group、集群 Cluster 则是在不同粒度实现了服务的隔离。
命名空间(应用环境隔离)
命名空间(Namespace):Nacos 服务中最顶层、也是包含范围最广的概念,用于强制隔离类似环境或租户等场景;Nacos 的服务也需要使用命名空间来进行隔离。命名空间的默认值是public,在 Nacos 中通过命名空间(Namespace)+ 分组(Group)+ 服务名(Name)可以定位到一个唯一的服务实例。
为项目配置命令空间:
spring.cloud.nacos.discovery.namespace=name
命名空间配置:
分组名(环境|使用场景)
分组名(Group)是Nacos 中次于命名空间的隔离概念,区别于命名空间的强制隔离属性,分组属于个弱隔离概念,主要用于逻辑区分些服务使用场景或不同应用的同名服务,最常用的情况主要是同个服务的测试分组和生产分组、或者将应用名作为分组以防止不同应用提供的服务重名。
为项目配置分组名:
spring.cloud.nacos.discovery.group=name
服务名
表示该服务实际的名字,般用于描述该服务提供了某种功能或能力。
在项目中的配置:
spring.application.name=simtek-cosimcloud-fmu
集群(Cluster)
加入Nacos的注册中心,如果服务名一致的服务会自动配置为集群:
如上所示,可以通过编辑配置权重。
保护阈值
保护阈值可以设置为0-1之间的浮点数(当前服务健康实例数/当前服务总实例数)。
- 当健康实例数占总服务实例数的比例小于该值时,无论实例是否健康,nacos将会把该服务所有的实例信息(健康的+不健康的)全部提供给消费者;
- 消费者可能访问到不健康的实例,导致请求失败,但也避免了流量压力将剩余实例被压垮形成雪崩效应;
- 最终,保证了整个系统的可用性。
服务路由类型
如果设置此值为 label(标签)模式,需要设置相应的标签表达式来匹配实例选择器(Selector),通过实例选择器可以完成自定义负载均衡策略。
实例(instance)
Nacos 在 instance级别存在ephemeral字段,用于表示注册的实例是否是临时实例还是持久化实例:
- 临时实例:不会在服务端持久化存储,需要通过上报心跳的方式进行保活,如果一段时间内没有上报心跳,则会被 Nacos 服务端踢除;再次加入后会重新将该实例注册。
- 持久化实例:即使注册实例的客户端进程不在,这个实例也不会从服务端删除,只会将健康状态设为不健康。
自定义实例的构建
nacos支持服务设置元数据(例如:所属的应用或者所在的机房),客户端可以根据服务下挂载的实例元信息,来自定义负载均衡模式。
Nacos 也提供了另外的注册实例接口,使得用户在注册实例时可以指定实例的属性:
void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException;
实例的定义如下:
public class Instance {
/**
* 实例唯一ID
*/
private String instanceId;
/**
* 对应IP
*/
private String ip;
/**
* 端口
*/
private int port;
/**
* 权重
*/
private double weight = 1.0D;
/**
* 实例健康状态。标识该实例是否健康,一般心跳健康检查会自动更新该字段
*/
private boolean healthy = true;
/**
* 是否启用
*/
private boolean enabled = true;
/**
* 是否为临时实例
*
* @since 1.0.0
*/
private boolean ephemeral = true;
/**
* 集群名称
*/
private String clusterName;
/**
* 服务名称
*/
private String serviceName;
/**
* 元数据
*/
private Map<String, String> metadata = new HashMap<String, String>();
}
服务信息在由服务提供者上报之后,由服务消费者获取,从而完成信息的传递。
二、nacos服务发现配置
版本适配
相关框架的版本适配:
| Spring Cloud Alibaba Version | Sentinel Version | Nacos Version | RocketMQ Version | Dubbo Version | Seata Version |
|---|---|---|---|---|---|
| 2021.0.1.0* | 1.8.3 | 1.4.2 | 4.9.2 | 2.7.15 | 1.4.2 |
| 2.2.7.RELEASE | 1.8.1 | 2.0.3 | 4.6.1 | 2.7.13 | 1.3.0 |
| 2.2.6.RELEASE | 1.8.1 | 1.4.2 | 4.4.0 | 2.7.8 | 1.3.0 |
| 2021.1 or 2.2.5.RELEASE or 2.1.4.RELEASE or 2.0.4.RELEASE | 1.8.0 | 1.4.1 | 4.4.0 | 2.7.8 | 1.3.0 |
| 2.2.3.RELEASE or 2.1.3.RELEASE or 2.0.3.RELEASE | 1.8.0 | 1.3.3 | 4.4.0 | 2.7.8 | 1.3.0 |
| 2.2.1.RELEASE or 2.1.2.RELEASE or 2.0.2.RELEASE | 1.7.1 | 1.2.1 | 4.4.0 | 2.7.6 | 1.2.0 |
| 2.2.0.RELEASE | 1.7.1 | 1.1.4 | 4.4.0 | 2.7.4.1 | 1.0.0 |
| 2.1.1.RELEASE or 2.0.1.RELEASE or 1.5.1.RELEASE | 1.7.0 | 1.1.4 | 4.4.0 | 2.7.3 | 0.9.0 |
| 2.1.0.RELEASE or 2.0.0.RELEASE or 1.5.0.RELEASE | 1.6.3 | 1.1.1 | 4.4.0 | 2.7.3 | 0.7.1 |
| Spring Cloud Alibaba Version | Spring Cloud Version | Spring Boot Version |
|---|---|---|
| 2021.0.1.0 | Spring Cloud 2021.0.1 | 2.6.3 |
| 2.2.7.RELEASE | Spring Cloud Hoxton.SR12 | 2.3.12.RELEASE |
| 2021.1 | Spring Cloud 2020.0.1 | 2.4.2 |
| 2.2.6.RELEASE | Spring Cloud Hoxton.SR9 | 2.3.2.RELEASE |
| 2.1.4.RELEASE | Spring Cloud Greenwich.SR6 | 2.1.13.RELEASE |
| 2.2.1.RELEASE | Spring Cloud Hoxton.SR3 | 2.2.5.RELEASE |
| 2.2.0.RELEASE | Spring Cloud Hoxton.RELEASE | 2.2.X.RELEASE |
| 2.1.2.RELEASE | Spring Cloud Greenwich | 2.1.X.RELEASE |
| 2.0.4.RELEASE(停止维护,建议升级) | Spring Cloud Finchley | 2.0.X.RELEASE |
| 1.5.1.RELEASE(停止维护,建议升级) | Spring Cloud Edgware | 1.5.X.RELEASE |
配置
dependencyManagement元素
dependencyManagement元素提供了一种管理依赖版本号的方式。在dependencyManagement元素中声明所依赖的jar包的版本号等信息,那么所有子项目再次引入此依赖jar包时则无需显式的列出版本号。
dependencyManagement中定义的只是依赖的声明,并不实现引入,因此子项目需要显式的声明需要用的依赖。
为子项目指定依赖版本:
<dependencyManagement>
<dependencies>
<!-- SpringCloud 微服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot 依赖配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud Alibaba 微服务 -->
<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>
<!-- Alibaba Nacos 配置 -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${alibaba.nacos.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- yml提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 解决版本不再默认优先加载bootstrap.yml文件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>ObsApplication</mainClass>
<excludeDevtools>true</excludeDevtools>
<includeSystemScope>true</includeSystemScope>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
子项目的配置:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
yml的配置:
# Tomcat
server:
port: 6002
spring:
application:
name: simtek-fmu
profiles:
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: ${NACOS_ADDR:127.0.0.1:6100}
group: cosimcloud
namespace: public
maven依赖中的<scope>provided</scope>
- compile:默认的scope,表示 dependency 都可以在生命周期中使用;而且会传递到依赖的项目中
- provided:表明了dependency 由JDK或者容器提供,只能作用在编译和测试时,同时没有传递性
- system:跟provided 相似,但是在系统中要以外部JAR包的形式提供,maven不会在repository查找它
- runtime:表示dependency不作用在编译时,但会作用在运行和测试时
- test:表示dependency作用在测试时,不作用在运行时
@EnableDiscoveryClient注解
@EnableDiscoveryClient能够让注册中心发现,扫描到该服务,不局限注册中心;而注解@EnableEurekaClient只适用于Eureka作为注册中心。
在启动类添加注解:
@SpringBootApplication
@EnableDiscoveryClient
public class CosimcloudFmuApplication {
public static void main(String[] args) {
SpringApplication.run(CosimcloudFmuApplication.class, args);
}
}
三、nacos配置中心
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。
Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。
引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
yml配置:
file-exetension为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension来配置。目前只支持properties和yaml类型。shared-configs表示共享配置
spring:
cloud:
nacos:
config:
# 配置中心地址
server-addr: ${NACOS_ADDR:127.0.0.1:6100}
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- ${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}