nacos
- 一,介绍
- 1. 什么是Spring Cloud Alibaba Nacos
- 2. Nacos的特点和优势
- 二,安装和配置
- 三,创建项目
- 第一步,创建父工程
- 第二步,创建基础公共模块
- 第三步,创建服务模块
- 第四步,开启多个实例
- 四,服务注册和发现
- 一,注册服务
- 二,远程调用 & 负载均衡
- 1. RestTemplate远程调用
- 1.1、添加依赖
- 1.2、添加配置类
- 1.3、应用
- 2. RestTemplate负载均衡
- 2.1 添加依赖
- 2.2 添加 @LoadBalanced 注解
- 2.3 应用
- 3. Feign实现服务调用
- 3.1 什么是Feign
- 3.2 使用feign
- 三,资源的隔离和分离
- 1. 命名空间
- 2. 服务分组
- 五,配置管理
- 1. 简单使用
- 第一步:添加依赖
- 第二步:配置Nacos地址
- 第三步:创建Nacos配置
- 第四步:启动服务
- 第五步:使用配置
- 2. 数据库配置
- 第一步:创建Nacos配置
- 第二步:配置Nacos地址
- 第三步:数据库配置类
- 第四步:启动应用程序
- 3. Namespace(命名空间)
- 第一步 创建命名空间
- 第二部 创建配置
- 第三步 使用dev命名空间中的配置
- 4. spring.profiles.active
- 第一步 创建配置
- 第二步 配置nacos地址
- 4. Group(分组)
- 5. Namespace和Group的区别
- 6. 共享配置
- 第一步 创建配置
- 第二步 配置nacos地址
- 方式一:extension-configs
- 方式二:shared-configs
- 7. 优先级
- 8. 动态配置刷新
一,介绍
- springboot :2.6.11
- springcloud:2021.0.4
- springcloudAlibaba: 2021.0.4.0
- nacos: 2.2.1
- IntelliJ IDEA 2022.3.2
1. 什么是Spring Cloud Alibaba Nacos
Spring Cloud Alibaba Nacos是一个可视化的动态服务发现、配置管理和服务管理平台。它是Spring Cloud和Alibaba的技术协作,旨在为Spring Cloud应用提供自动化的服务注册和发现、动态配置管理和智能路由等功能。Nacos提供了一下核心功能:
- 服务注册与发现:支持基于DNS和HTTP/REST的服务注册与发现功能。
- 配置中心:支持数据持久存储,并为需要动态配置的微服务提供统一的外部化配置。
- 动态DNS服务:Nacos内置了一个简单的DNS服务器,允许每个微服务实例动态变化其IP地址,同时支持权重路由策略。
- 服务和工作流管理:Nacos提供了服务管理、健康检查、流控和降级等一系列开箱即用的服务治理特性,支持可视化的服务管理和定位。
Spring Cloud Alibaba Nacos提供了一套全面的解决方案,可以帮助构建弹性、可靠、高可用的微服务应用。
2. Nacos的特点和优势
Nacos的特点与优势主要体现在以下几个方面:
- 服务注册与发现:Nacos支持三种不同的服务注册方式(自动、手动、DNS),并且支持服务健康检查、负载均衡和故障切换等功能,从而能够快速高效地处理服务实例的变化。
- 配置管理:Nacos支持灵活的配置管理,能够为不同的应用程序提供不同的配置信息,并且支持动态更新和灰度发布等功能,让系统配置管理变得更加高效和可控。
- 动态DNS:Nacos支持服务实例的动态IP地址,能够支持根据实例权重的路由和自动拓扑发现等功能,对实现基于服务的动态路由和负载均衡非常有帮助。
- 高可用:Nacos可以通过配置集群实现高可用,保证服务注册、配置管理和服务发现的可靠性,并且支持数据备份和节点自动切换等功能,对于构建大规模分布式系统非常有帮助。
- 集成Spring Cloud:Nacos可以和Spring Cloud完美集成,支持Spring Cloud应用的自动化注册、配置和发现,以及负载均衡和服务熔断等特性,使得Spring Cloud应用的搭建和维护变得更加容易和高效。
- 可视化控制台:Nacos提供了一个web可视化的控制台,让开发者可以方便地对服务进行管理和监控。
Nacos是一款功能强大的服务发现与配置管理平台,对于构建弹性、可靠的分布式应用非常有帮助。
二,安装和配置
springcloud-alibaba (01)linux下Nacos单节点安装和部署
三,创建项目
第一步,创建父工程
- 第一步打开idea找到新建项目,点击创建
- 打开父项目springcloud-01删除src目录,打开pom文件,添加以下内容
<?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>org.buba</groupId>
<artifactId>springcloud-01</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.6.11</version>
</parent>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.4.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
这是一个 Maven 项目的 POM 文件,使用了 Spring Cloud 和 Spring Cloud Alibaba 相关的依赖。
其中,<parent>
标签指定了此项目的父项目是 spring-boot-starter-parent
,版本号定为 2.6.11
。
<dependencyManagement>
标签则用于中央管理项目的依赖版本,其中列出了需要用到的 Spring Cloud 和 Spring Cloud Alibaba 的依赖版本。该 POM 文件只是项目的一部分,继承之后可以在子项目中声明所需的依赖即可使用。
第二步,创建基础公共模块
在Spring Cloud微服务架构中,通常建议将一些公共类、公共配置、公共工具等重用的资源提取出来,放置在独立的公共模块中,让服务消费者和服务提供者都可以使用。
这种做法的好处主要有以下几个方面:
-
提高代码复用率:将共用的代码、配置、工具等放置在独立的公共模块中,可以方便地在不同的微服务中进行重用,避免了重复编写和维护的问题,提高了代码复用率,降低了工作量和维护成本。
-
强化服务间的边界:将公共资源从具体的微服务中分离出来,可以让微服务之间的边界更加清晰明确。当某个服务需要使用公共模块中的资源时,只需在pom文件中添加对公共模块的依赖,即可使用公共模块中的资源,这有助于降低服务之间的耦合度。
-
简化开发和维护:将公共资源放置在独立的公共模块中,可以让开发人员更加专注于业务逻辑的开发,不必过多地关注底层技术细节和公共资源的管理,从而提高开发效率和代码可维护性。
总之,创建公共模块是一种促进代码复用、减少重复劳动、降低系统耦合度、提高开发效率和代码可维护性的好方法,是微服务架构中推崇的一种开发模式。
- springcloud-01右键-新建-添加模块
- 创建一个基础公共模块叫common,父项目选择springcloud-01
- 给子项目common的pom文件里添加以下内容
<?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>com.buba</groupId>
<artifactId>springcloud-01</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>common</artifactId>
<packaging>pom</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
第三步,创建服务模块
** 创建user模块和order模块,步骤和第二步一样,给他们的pom文件分别添加common公共模块**
<dependencies>
<dependency>
<groupId>com.buba</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
然后给两个模块创建SpringBoot主类
order启动类
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
System.out.println("ok");
}
}
使用@SpringBootApplication注解标注,表示它是一个Spring Boot应用程序的主类。在main方法中,使用SpringApplication的静态方法run来启动应用程序,并指定该类为启动类,args为传递给应用程序的命令行参数。在启动应用程序后,会输出"ok"。
user启动类
@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
System.out.println("ok");
}
}
使用@SpringBootApplication注解标注,表示它是一个Spring Boot应用程序的主类。在main方法中,使用SpringApplication的静态方法run来启动应用程序,并指定该类为启动类,args为传递给应用程序的命令行参数。在启动应用程序后,会输出"ok"。
加入配置文件
oerder的yml文件
spring:
application:
name: order-server
datasource:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:/mapper/*.xml
type-aliases-package: com.buba.entity
server:
port: 7002
user的yml文件
spring:
application:
name: user-server
datasource:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:/mapper/*.xml
type-aliases-package: com.buba.entity
server:
port: 7001
项目结构
第四步,开启多个实例
先运行要多开的服务,然后更改端口号,进入IDEA
的运行设置,选择“Edit configurations…”
点击修改选项(M)—> 选择允许多个实例 —> 应用 —> 确定
最后再次运行服务就可以了
四,服务注册和发现
一,注册服务
将用户模块作为微服务注册到nacos
- 在pom.xml文件中引入spring-cloud-starter-alibaba-nacos-discovery依赖。
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 在需要进行服务注册的服务应用中,添加@EnableDiscoveryClient注解
@SpringBootApplication
@EnableDiscoveryClient
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
System.out.println("ok");
}
}
- 在application.properties或者application.yml文件中配置Nacos的服务注册中心地址。
application.properties格式:
spring.cloud.nacos.discovery.server-addr=192.168.157.130:8848
application.yml格式:
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.157.130:8848
我的application.yml文件:
spring:
application:
name: user-server
datasource:
druid:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
cloud:
nacos:
discovery:
server-addr: 192.168.157.130:8848
mybatis:
mapper-locations: classpath:/mapper/*.xml
type-aliases-package: com.buba.entity
server:
port: 7001
-
将order模块作为微服务注册到nacos就可以了(步骤和上面一样)
-
启动服务报错:(没报错就跳过)
- Server check fail, please check server 192.168.157.130 ,port 9848 is available , error ={}
- java.util.concurrent.TimeoutException: Waited 3000 milliseconds
Nacos 高版本(如 2.1.4)需要打开 9848 端口是因为 Nacos Server 在高版本中引入了 gated 模块,这个模块的作用是对 Nacos Server 节点之间的数据同步进行加速,具体来说就是通过 gated 模块实现了 Server Cluster 内部的 p2p 数据传输和结构化布局。而这个模块所需要的端口就是 9848 端口。
如果不启用 gated 模块,可以通过修改 Nacos Server 的配置文件,将 gated.enabled 属性设置为 false 来关闭 gated 模块,这样就可以不需要使用 9848 端口了。但是,如果想要使用 gated 模块,则必须打开 9848 端口,否则会导致 Nacos 无法正常工作。
开启9848端口
· 开启9848端口号
firewall-cmd --zone=public --add-port=9848/tcp --permanent
· 刷新(重新加载端口号)
firewall-cmd --reload
· 查看8848端口号是否已经开启
firewall-cmd --query-port=9848/tcp
-
启动服务, 观察nacos的控制面板中是否有注册上来的user微服务和order服务
二,远程调用 & 负载均衡
远程调用之前给服务写一个能访问的接口
order的controller
@RestController
@RequestMapping("/order")
public class OrderController {
@RequestMapping("/get-01")
public Integer orderInit() {
return 111;
}
}
1. RestTemplate远程调用
RestTemplate是Spring提供的一个访问Http服务的客户端类
1.1、添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
1.2、添加配置类
@Configuration
public class RestConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
1.3、应用
DiscoveryClient是Spring Cloud提供的一种获取服务注册信息的客户端,它可以通过Nacos服务注册中心来获取所有注册的服务。
在Spring Cloud应用程序中,如果我们需要调用其他微服务的API接口时,首先需要解析该API接口所属的微服务的IP地址和端口号等信息。使用DiscoveryClient就可以很方便地获取到由Nacos服务注册中心维护的微服务信息。
DiscoveryClient包含了查询服务注册表的方法,通过该方法可以获取一组服务的Instance列表,每个Instance代表一个运行的实例,包含实例ID、主机名、端口号、URI、服务名称等信息。根据Instance的信息,就可以配置微服务之间的相互调用。
在实际应用中,我们可以将DiscoveryClient注入到Controller或Service等组件中,从而可以很方便地获取其他微服务的实例信息。通常情况下,我们会根据需要的服务名称,从DiscoveryClient获取服务名对应的实例列表,然后再选择其中一个实例来进行调用。如下面的代码所示:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test")
public Integer test(){
// 从nacos中获取服务实例
ServiceInstance serviceInstance = discoveryClient.getInstances("order-server").get(0);
// 获取服务IP和端口号
String url = serviceInstance.getHost() + ":" + serviceInstance.getPort();
// 通过restTemplate调用订单微服务
return restTemplate.getForObject("http://" + url + "/order/get-01", Integer.class);
}
}
2. RestTemplate负载均衡
2.1 添加依赖
spring-cloud-starter-loadbalancer
是 Spring Cloud 中用于实现负载均衡的一个 starter 依赖,它提供了负载均衡的能力和 API,让开发者能够简单地实现在服务之间进行负载均衡。
<dependencies>
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>alibaba-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
2.2 添加 @LoadBalanced 注解
在 RestConfig类中创建了一个 RestTemplate Bean,并添加了 @LoadBalanced 注解,用于启用负载均衡能力。
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
这是一个 Spring 配置类,使用 @Configuration
注解标识。这个类中定义了一个名为 restTemplate
的 Bean,它的类型是 RestTemplate
。同时,这个 Bean 上使用了 @LoadBalanced
注解,表示这个 RestTemplate
会使用 Spring Cloud 的负载均衡功能。
具体来说,当我们使用 @LoadBalanced
注解来标注一个 RestTemplate
类型的 Bean 时,Spring 自动为其添加一个拦截器 LoadBalancerInterceptor
,这个拦截器会在发送请求时进行拦截,从而自动将请求转发到多个服务实例中去,并进行负载均衡。简单来说,当我们使用这个被 @LoadBalanced
注解标记过的 RestTemplate
类型的 Bean 时,就可以让 Spring 自动帮我们实现负载均衡。
2.3 应用
举个例子,假如我们有一个名为 order-serve
的微服务,而这个微服务部署在多个服务器上,我们可以通过如下方式来调用它
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test")
public Integer test(){
String url = "http://order-server/order/get-01";
return restTemplate.getForObject(url,Integer.class);
}
在上例中,我们通过注入 restTemplate
Bean 来调用其他微服务。由于 restTemplate
上使用了 @LoadBalanced
注解,其负责管理负载均衡,因此 Spring 会根据服务名 service-name
自动将请求分发到多个实例中去,并实现负载均衡。
3. Feign实现服务调用
OpenFeign是一个用于客户端服务调用的工具,同样也支持负载均衡。OpenFeign的负载均衡策略主要有以下几种:
- 轮询策略(Round Robin):即依次按照服务的实例列表进行轮流调用,均衡地将请求分配给每一个实例。
- 随机策略(Random):即直接从服务实例列表中随机选择一个实例进行调用。
- 最小连接策略(Least Connections):即根据当前实例的连接数来进行调用,当前连接数越小的实例被选中的概率越大。
- 响应时间加权策略(Response Time Weighted):即根据服务实例的响应时间来进行调用,响应时间越短的实例被选中的概率越大。
- IP Hash算法策略(IP Hash):即根据客户端请求的IP地址来进行hash算法计算,将请求分发到同一IP地址的服务实例上。
在实际开发中,根据具体的业务场景选择合适的负载均衡策略非常重要,可以保证服务的高可用性和性能。
3.1 什么是Feign
Feign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地服务一样简单, 只需要创建一个接口并添加一个注解即可。
Nacos很好的兼容了Feign, Feign默认集成了 Ribbon, 所以在Nacos下使用Fegin默认就实现了负载均衡的效果
3.2 使用feign
3.2.1 添加feign的依赖
<dependencies>
<dependency>
<groupId>com.buba</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
3.2.2 添加@EnableFeignClients注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients//开启Fegin
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
System.out.println("ok");
}
}
3.2.3 创建feign接口添加FeignClient注解
@FeignClient注解是Spring Cloud Feign的核心注解之一,它可以用来定义一个Feign客户端,并指定要调用的服务名称、负载均衡策略、熔断器等参数。
@FeignClient注解可以使用的参数如下:
- name:指定要调用的服务名称,这个名称通常是注册中心中的服务名称。
- url:指定要调用服务的URL地址,这个URL地址可以是服务的IP地址或者域名。
- path:指定调用服务的URL路径,这个路径会添加到调用服务的地址之后,用于指定具体的API路径。
- contextId:指定这个Feign客户端的上下文ID,以避免和其他Feign客户端发生冲突。
- configuration:指定Feign的配置类,这个配置类可以用来实现自定义的负载均衡、熔断等操作。
- fallback:指定熔断器的实现类,在服务调用失败时可以使用这个类来提供fallback实现。
- decode404:指定当HTTP响应状态码为404时,是否抛出异常。
- primary:指定这个Feign客户端是否为主要客户端,这个属性通常在一个接口有多个Feign客户端时使用。
以上参数中,name和url是最常用的两个参数,它们可以用来指定要调用的服务名称和服务地址。在实际应用中,我们通常会根据具体的需求来选择这两个参数的使用方式。
@FeignClient(name = "order-server",path = "/order")//声明调用的提供者的name
public interface OrderFeign {
//指定调用提供者的哪个方法
//@FeignClient+@GetMapping 就是一个完整的请求路径 http://order-server/order/get-01
@GetMapping("/get-01")
Integer orderInit();
}
3.2.4 在Controller中注入OrderFeign,并使用它调用远程服务的API接口。
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private OrderFeign orderFeign;
@GetMapping("/test")
public Integer test(){
return orderFeign.orderInit();
}
}
以上就是使用Nacos实现Spring Cloud Feign的服务调用的步骤。在实际应用中,FeignClient可以根据方法的声明来生成HTTP请求,从而简化了服务调用的过程。然而,在使用FeignClient时也需要注意一些问题,如方法参数必须使用注解来标记、方法返回值类型必须与实际返回值类型一致等。
三,资源的隔离和分离
Nacos是一个动态服务发现、配置管理和服务治理平台,其中分组和命名空间是其两个重要的概念。
- 分组
分组是将一组实例隔离到同一分组中,以便于组内的实例共享配置、元数据等信息。在分组级别上,Nacos支持配置管理、命名空间、服务管理等功能。分组的应用场景包括:多环境多配置、集群管理、配置隔离等。
- 命名空间
命名空间是一组资源的集合,每个命名空间对应一个隔离的数据存储空间。不同命名空间之间的数据是相互隔离的,每个命名空间可以独立使用Nacos的各项服务,并不会影响其他命名空间。命名空间的应用场景包括:多租户应用隔离、多环境测试隔离等。
总之,Nacos的分组和命名空间都是用来实现资源隔离的概念,不同的是分组是指将实例分到同一组来共享资源,而命名空间则是指隔离不同的资源集合,以实现数据隔离和管理。
1. 命名空间
1.1 创建命名空间dev
NameSpace(默认的NameSpace是”public“ NameSpace可以进行资源隔离,比如我们dev环境下的NameSpace下的服务是调用不到prod的NameSpace下的微服务)
1.2 配置微服务命名空间
可以通过设置 namespace
参数来指定所属的命名空间,例如:
spring:
application:
name: order-server
cloud:
nacos:
discovery:
server-addr: 192.168.109.149:8848
namespace: 8ab71548-1ea8-4823-9152-9285fbf82ad9
namespace的值就是命名空间id
2. 服务分组
服务分组是用于对注册的服务进行分类和划分的,可以根据实际业务需求将不同的服务划分到不同的分组中,以便更好地进行服务的维护和管理。在注册服务时,可以通过 group
参数来指定服务所属的分组,例如:
spring:
cloud:
nacos:
discovery:
group: group-01
- 配置微服务分组
spring:
application:
name: user-server
cloud:
nacos:
discovery:
server-addr: 192.168.109.149:8848
namespace: 8ab71548-1ea8-4823-9152-9285fbf82ad9
group: group-01
- 启动user和order服务,查看分组名称
五,配置管理
使用nacos作为配置中心,其实就是将nacos当做一个服务端,将各个微服务看成是客户端,我们将各个微服务的配置文件统一存放在nacos上,然后各个微服务从nacos上拉取配置即可
1. 简单使用
第一步:添加依赖
在pom.xml文件中添加以下依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
第二步:配置Nacos地址
先把application.yml文件改成bootstrap.yml
这是因为在 Spring Boot 应用程序启动时,会优先加载 bootstrap.yml
或 bootstrap.properties
文件中的配置项,然后再加载 application.yml
或 application.properties
文件中的配置项。因此,我们可以使用 bootstrap.yml
或 bootstrap.properties
文件来配置一些在应用程序启动前需要加载或初始化的资源,比如应用程序上下文和配置中心的连接等。
具体来说,在使用 Nacos 配置中心时,我们需要在 bootstrap.yml
或 bootstrap.properties
文件中配置一些连接 Nacos 配置中心的参数,比如 Nacos 配置中心的地址和命名空间等。这些参数必须在应用程序启动前加载,才能保证应用程序能够正确地连接到 Nacos 配置中心并获取配置项的值。如果将这些参数放在 application.yml
或 application.properties
文件中,那么由于在应用程序启动时优先加载该文件,可能会出现应用程序无法正确连接到 Nacos 配置中心的情况。
因此,为了避免出现这种问题,建议将连接 Nacos 配置中心的参数放在 bootstrap.yml
或 bootstrap.properties
文件中。这样可以保证在应用程序启动前先加载这些参数,避免出现连接配置中心失败的情况。
然后添加以下配置:
spring:
cloud:
nacos:
config:
server-addr: 192.168.157.130:8848
shared-configs: config
discovery:
server-addr: 192.168.157.130:8848
server-addr
参数指定了 Nacos 配置中心和服务发现的服务器地址。shared-configs
参数用于开启共享配置功能,配置中心中的公共配置可以被多个应用程序同时读取。
第三步:创建Nacos配置
在Nacos控制台中创建配置文件,例如:config。在该文件中添加需要配置的属性,
properties格式:
bilal=000000
yaml格式:
bilal: yaml
第四步:启动服务
启动Spring Cloud应用程序后,Nacos会自动将配置文件加载到应用程序中。
第五步:使用配置
可以在应用程序代码中使用@Value注解获取配置属性的值
@Value("${bilal}")
private String author;
这样就可以在应用程序中访问配置属性的值了。
2. 数据库配置
可以将数据库的配置移至配置中心,并修改工程中数据源的配置
第一步:创建Nacos配置
在Nacos控制台中创建配置文件,datasource.yml。在该文件中添加需要配置的数据源
第二步:配置Nacos地址
先把application.yml文件改成bootstrap.yml然后添加以下配置:
spring:
application:
name: user-server
cloud:
nacos:
config:
server-addr: 192.168.157.130:8848
shared-configs: datasource.yml
discovery:
server-addr: 192.168.157.130:8848
mybatis:
mapper-locations: classpath:/mapper/*.xml
type-aliases-package: com.buba.entity
server:
port: 7001
第三步:数据库配置类
创建数据库配置类DataSourceConfig
@Configuration
public class DataSourceConfig {
@Value("${spring.datasource.druid.username}")
private String username;
@Value("${spring.datasource.druid.password}")
private String password;
@Value("${spring.datasource.druid.url}")
private String url;
@Value("${spring.datasource.druid.driver-class-name}")
private String driverClassName;
@Bean
public DataSource dataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setDriverClassName(driverClassName);
return druidDataSource;
}
}
第四步:启动应用程序
启动Spring Cloud应用程序后,Nacos会自动将配置文件加载到应用程序中
3. Namespace(命名空间)
Namespace 主要是将不同应用程序的配置项进行隔离、分离。在同一个 Nacos 实例中,可以创建多个 Namespace,并为每个 Namespace 分配不同的访问权限和配置项。这样做可以有效避免配置项之间的冲突,同时也方便了配置项的管理和维护。
第一步 创建命名空间
第二部 创建配置
在新创建的dev空间中创建配置
新建配置
author: bilal
spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
第三步 使用dev命名空间中的配置
spring:
application:
name: user-server
cloud:
nacos:
config:
server-addr: 192.168.157.130:8848
shared-configs: datasource-dev.yml
namespace: 648ec1b8-5520-4500-b4c9-e95eb0d7c450
discovery:
server-addr: 192.168.157.130:8848
server:
port: 7001
以上配置中:
nacos
是 Spring Cloud Alibaba Nacos 的命名空间。config
是 Nacos 配置中心的配置命名空间,用于存储应用程序的配置。server-addr
参数指定了 Nacos 配置中心的服务器地址。shared-configs
参数开启了共享配置功能,指定了要共享的配置文件名为datasource-dev.yml
,这里的配置文件要存在于 Nacos 配置中心中。namespace
参数指定了命名空间,每个命名空间的配置都是相互独立的,可以在同一个 Nacos 集群中维护多个独立的配置中心。在进行配置管理时需要指定命名空间,否则会操作默认的命名空间。在上面的配置中,我们指定了命名空间为648ec1b8-5520-4500-b4c9-e95eb0d7c450
,这个命名空间需要在 Nacos 控制台中手动创建。
注意,当使用共享配置功能时,可以在多个应用程序中共享一个配置文件,这样做可以减少配置文件重复的问题,提高配置文件的管理效率。但是使用共享配置时要注意以下问题:
- 如果共享的配置在 Nacos 配置中心中不存在,应用程序启动时会报错。
- 如果共享的配置文件的内容被修改,所有引用该配置文件的应用程序都会受到影响,这可能会导致不同应用程序之间的冲突。因此,在使用共享配置时要确保配置文件内容的正确性,并且避免在运行中随意更改共享的配置文件。
4. spring.profiles.active
spring.profiles.active
可以直译为“Spring环境配置文件激活属性”。它是Spring Boot应用程序的一个关键属性,用于在不同的环境中加载不同的配置文件。可以通过该属性指定加载的配置文件,比如在开发环境中加载dev环境的配置文件,在生产环境中加载prod环境的配置文件。
通常,在开发过程中,会使用不同的配置文件来管理应用程序的不同配置。例如,如果正在开发一个 Web 应用程序,可能需要为不同的环境(如开发、测试和生产)使用不同的数据库连接或其他服务。通过使用 spring.profiles.active
属性,就可以轻松地切换这些配置,而无需修改代码或重新打包应用程序。
第一步 创建配置
在配置列表中创建两个配置,名字格式:服务名-profile名.后缀名
user-server-test.yml
author: bilal-test.yml
tame: 12345678
spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
user-server-prod.yml
author: bilal-prod.yml
tame: 12345678
spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
第二步 配置nacos地址
spring:
application:
name: user-server
cloud:
nacos:
discovery:
server-addr: 192.168.157.129:8848
config:
server-addr: 192.168.157.129:8848
file-extension: yml
namespace: 8ab71548-1ea8-4823-9152-9285fbf82ad9
profiles:
active: prod
最后一行profiles.active指定了当前应用程序的激活环境配置文件为"prod"。
也就是说,当该应用程序启动时,会自动加载位于"classpath:/bootstrap.yml"
文件中的配置,并且会根据激活的环境变量加载不同环境的配置文件,如user-server-prod.yml,这样可以方便地在不同的环境中启动应用程序,并加载不同的配置文件,从而达到灵活部署和管理的目的。
4. Group(分组)
在 Nacos 配置中心中,分组是将配置项按照类别进行划分的一种方式。每个配置项都可以属于一个或多个分组,而每个分组都拥有自己的配置集(Config Group)。
通过使用分组,我们可以更好地组织和管理配置项,将它们按照不同的功能或用途进行分类,从而避免配置项之间的混淆和冲突。
在 Nacos 配置中心中,分组名称的长度不能超过 128 个字符,可以包含字母、数字、下划线、中划线和点号。当我们创建一个配置集时,可以为它指定一个分组名称,将配置项添加到这个配置集中时,也可以指定它所属的分组。
在使用 Nacos 配置中心时,我们可以通过 spring.cloud.nacos.config.group
参数来指定应用程序要访问的配置集所属的分组。如果没有指定分组名称,默认使用 DEFAULT_GROUP
。
5. Namespace和Group的区别
在 Nacos 配置中心中,Namespace(命名空间)和 Group(分组)都是对配置项进行管理的方式,但它们的作用不同。
Namespace 主要是将不同应用程序的配置项进行隔离、分离。在同一个 Nacos 实例中,可以创建多个 Namespace,并为每个 Namespace 分配不同的访问权限和配置项。这样做可以有效避免配置项之间的冲突,同时也方便了配置项的管理和维护。
而 Group 则是为了将同一个应用程序中的配置项按照不同的用途或者功能进行分类,从而方便配置项的组织和管理。在同一个 Namespace 中,可以有多个 Group,每个 Group 都有自己的配置项集合。可以通过在配置文件中指定 Group 名称来指定要取用的配置项。
简单来说,Namespace 主要是解决多应用之间的隔离问题,而 Group 主要是解决单个应用内部的配置项组织和管理问题。
6. 共享配置
在 Nacos 配置中心中,共享配置(Shared Configuration)是一种通过多个应用程序共享同一个配置信息的方式。它通常用于各个应用程序之间需要共享一些公共配置信息的场景,比如数据库连接信息、Redis 集群地址、日志级别等等。
在配置中心中开启共享配置后,所有访问该配置中心的应用程序都可以通过相同的配置项名称和分组名称来获取和更新配置信息。这就避免了每个应用程序都需要单独维护这些公共配置信息的麻烦。
使用共享配置时,需要注意以下几点:
-
为了确保共享配置的安全和正确性,建议使用专门的、受限的账号来访问配置中心,并为每个应用程序授予适当的访问权限;
-
避免使用过多的共享配置,因为共享配置可能会影响多个应用程序,如果出现问题,可能会造成不可预料的影响;
-
注意共享配置的版本控制和更新时间,确保每个应用程序都在使用最新的配置信息。
第一步 创建配置
先去创建两个配置
mysql.yml里面的内容
author: bilal1
spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
redis.yml里面的内容
username: redis
password: 123456
db: 0
第二步 配置nacos地址
方式一:extension-configs
spring:
application:
name: user-server
cloud:
nacos:
discovery:
server-addr: 192.168.157.129:8848
config:
server-addr: 192.168.157.129:8848
namespace: 8ab71548-1ea8-4823-9152-9285fbf82ad9
extension-configs[0]:
data-id: mysql.yml
# 默认为DEFAULT_GROUP
group: DEFAULT_GROUP
# 是否动态刷新,默认为false
refresh: true
extension-configs[1]:
data-id: redis.yml
group: DEFAULT_GROUP
refresh: true
新版本idea在yml格式的配置文件中使用extension-configs[n] 会有,重复的配置键 spring.cloud.nacos.config.extension-configs
的警告
不用管他启动项目就行,你想不想看到警告,可以在项目的Settings/Preferences -> Experimental
中勾选Extensions and Frameworks
,这样就可以正常使用extension-configs
属性了。
或者extension-configs属性删掉在resources下面创建一个bootstrap.properties里面写以下内容就没有警告了。
#mysql
spring.cloud.nacos.config.shared-configs[0].data-id=mysql.yml
spring.cloud.nacos.config.shared-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].refresh=true
#redis
spring.cloud.nacos.config.shared-configs[1].data-id=redis.yml
spring.cloud.nacos.config.shared-configs[1].group=DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[1].refresh=true
方式二:shared-configs
spring:
application:
name: user-server
cloud:
nacos:
config:
server-addr: 192.168.157.130:8848
shared-configs: mysql.yml,redis.yml
namespace: 8ab71548-1ea8-4823-9152-9285fbf82ad9
discovery:
server-addr: 192.168.157.130:8848
shared-configs 的值写Data Id就可以了
在Nacos中,shared-configs
和extension-configs
都是用于存储配置信息的Namespace。它们的区别是:
shared-configs
:
- 用于存储共享的配置,可以被多个Group和DataID使用
- 配置信息存储在mysql数据库中,支持历史版本管理、回滚等功能
- 权限控制粒度较粗,实例级别的权限控制
extension-configs
:
- 用于存储应用扩展配置,通常每个应用或每个数据源对应一个extension-configs
- 配置信息存储在本地磁盘上,不支持版本管理
- 权限控制粒度更细,可以对每个Namespace进行权限控制
所以,总体来说:
shared-configs
更适合共享的、需要历史管理的配置。权限控制较粗糙,但由于配置共享,粗粒度也能满足需求。
extension-configs
更适合应用扩展配置,权限控制更加细致,配置信息没有历史版本管理,以追求高性能为主要考量。
使用场景举例:
shared-configs
: 可以存储数据库连接信息,应用通用配置等。这些配置通常需要版本管理,且需要共享。
extension-configs
: 可以存储某个应用自身的扩展配置,不需要跨应用共享,也不需要版本管理。可以在此Namespace下针对每个应用创建属于自己的Data ID来存储配置。
所以总的来说,这两个Namespace各有优势,可以根据不同的配置场景和需求选择合适的Namespace进行配置存储和管理。
7. 优先级
配置文件优先级(由高到低):
bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml
8. 动态配置刷新
方式一: 硬编码方式
@RestController
public class NacosConfigController {
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping("/nacos-config-test1")
public String nacosConfingTest1() {
return applicationContext.getEnvironment().getProperty("config.appName");
}
}
方式二: 注解方式(推荐)
@RestController
@RefreshScope//只需要在需要动态读取配置的类上添加此注解就可以
public class NacosConfigController {
@Value("${config.appName}")
private String appName;
@GetMapping("/nacos-config-test2")
public String nacosConfingTest2() {
return appName;
}
}
)