Nacos不仅具有注册中心的功能,还具有注册管理的功能
可以使用统一配置管理,来配置更改热更新,整体结构如下

前提条件: 你已经把上面的 '实用篇-Nacos注册中心' 学完了,并且项目也跟着做了。我们下面会使用到上面的项目。具体操作如下
第一步: 浏览器访问http://localhost:8848/nacos/index.html,用户名和密码都是nacos,登录进管理面板
第二步: 在管理面板添加配置


注意上图中配置内容中的不是把项目中application.yml所有配置都写过来,而是只写有热更新需求的配置,配置完点击发布即可

上面我们只是把这个配置文件做出来了,至于微服务如何去读取我们做出来了的配置文件,下面会学习
在微服务去获取上面Nacos做出来了的配置文件,步骤如下图

具体步骤如下
第一步: 在UserService微服务的pom.xml,添加如下,引入Nacos的配置管理客户端依赖
- <dependency>
- <groupId>com.alibaba.cloudgroupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
- dependency>
第二步: 在UserService微服务中的resources目录新建File,文件名是bootstrap.yml。注意bootstrap.yml文件是引导文件,优先级高于application.yml文件。添加如下
- spring:
- application:
- # 服务名称
- name: UserService
- profiles:
- # 环境,dev表示开发环境
- active: dev
- cloud:
- nacos:
- # nacos的服务地址
- server-addr: localhost:8848
- config:
- # 我们创建的dev命名空间
- namespace: d8ec5ecb-2268-4551-ac2d-f08953292b28
- # 文件后缀名
- file-extension: yaml
-
第三步: 把application.yml中删掉如下。跟刚刚的bootstrap.yml重复的代码给删掉,也就是如果代码重复的话只保留bootstrap.yml的代码,操作后application.yml文件如下
- server:
- port: 8081
- spring:
- datasource:
- url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
- username: root
- password:
- driver-class-name: com.mysql.jdbc.Driver
-
-
-
- # # 跨集群部署
- # discovery:
- # cluster-name: SH # 自定义集群的名字
-
- mybatis:
- type-aliases-package: cn.itcast.user.pojo
- configuration:
- map-underscore-to-camel-case: true
- logging:
- level:
- cn.itcast: debug
- pattern:
- dateformat: MM-dd HH:mm:ss:SSS
-
- #eureka:
- # client:
- # service-url:
- # # eureka的服务地址。如果有多个的话,逗号隔开。也就是把当前这个user-service微服务注册给哪个Eureka
- # defaultZone: http://localhost:8686/eureka
第四步: 验证UserService微服务有没有拉取到配置文件。在UserService微服务的web目录的UserController类里面添加如下
- //验证配置拉取是否成功,我们直接在这里去读取拉取过来的配置,如果能拉取就表示验证成功
- @Value("${pattern.dateformat}")
- private String dataformat;
-
- @GetMapping("now")
- public String now(){
- return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dataformat));
- }
第五步: 测试。重新启动UserService微服务,浏览器访问 http://localhost:8081/user/now
上面我们已经实现了读取Nacos上写的配置文件,但是存在一个问题,如果配置文件修改了那必须重启服务才能生效修改后的配置。
能不能让Nacos中写的配置文件实现热更新呢,也就是实时生效,不需要重新启动微服务
Nacos中的配置文件变更后,微服务无需重启就可以感知,实现的方式有两种,如下:
第一种: 在@Value注入的变量所在类(也就是我们上面的UserController类)上添加注解@RefreshScope
第一种的具体操作如下
第一步: 在UserService微服务的web目录的UserController类添加如下,并重新启动UserService微服务的实例
第二步: 修改浏览器上写的配置文件,修改为如下,点击发布
- pattern:
- dateformat: yyyy.MM.dd HH:mm:ss
第三步: 查看是否实现热更新,浏览器访问,可以看到,直接访问的是更新后的配置,而无需重启服务

第二种配置热更新方式是: 使用@ConfigurationProperties注解
第一步:在user-service项目下创建config/PatternProperties类
- package cn.itcast.user.config;
-
- import lombok.Data;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
-
- @Component
- @Data
- @ConfigurationProperties(prefix = "pattern") //配置属性前缀名
- public class PatternProperties {
- private String dateformat;
- }
第二步: 在user-service微服务项目的web目录的UserController类修改为如下
- package cn.itcast.user.web;
-
- import cn.itcast.user.config.PatternProperties;
- import cn.itcast.user.pojo.User;
- import cn.itcast.user.service.UserService;
- import lombok.extern.slf4j.Slf4j;
- import org.checkerframework.checker.units.qual.A;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.cloud.context.config.annotation.RefreshScope;
- import org.springframework.web.bind.annotation.*;
-
- import java.time.LocalDateTime;
- import java.time.format.DateTimeFormatter;
-
- @Slf4j
- @RestController
- @RequestMapping("/user")
- //@RefreshScope
- public class UserController {
-
- @Autowired
- private UserService userService;
-
- @Autowired
- private PatternProperties patternProperties;
-
- /**
- * 路径: /user/110
- *
- * @param id 用户id
- * @return 用户
- */
- @GetMapping("/{id}")
- public User queryById(@PathVariable("id") Long id) {
- return userService.queryById(id);
- }
-
- //验证配置拉取是否成功,我们直接在这里去读取拉取过来的配置,如果能拉取就表示验证成功
- // @Value("${pattern.dateformat}")
- // private String dataformat;
-
- @GetMapping("now")
- public String now(){
- return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat()));
- }
- }
第三步: 测试。重新启动UserService微服务,先访问一下能不能拿到配置文件里面的数据

修改nacos配置如下
点击发布,不重启项目,直接访问
两种微服务热更新的方式,总结
注意事项:
场景: 有一个配置属性,该配置属性在开发、生产、测试等环境下的值是一样的,我们就不用在每个配置文件里面都写一份,而是使用多环境配置共享。简单说就是把配置写在一个地方,不管环境怎么变,配置都能被加载。下面将进入学习
微服务启动时会从nacos里自动读取两种配置文件。如下
注意除了这两种nacos '线上配置文件' ,微服务还有自身的application.yml配置文件(叫 '本地配置文件' )。所以微服务启动时会自动读取这三种
(1)、当微服务启动时,会根据环境加载对应的配置文件
(2)、当微服务启动时,必然会加载这类的配置文件。我们可以把多环境共享配置写入这个文件
(3)、微服务自身的application.yml配置文件(叫 '本地配置文件' )
案例如下
第一步: 在浏览器的nacos管理界面添加一个新的配置文件,作为我们下面要学的多环境配置文件



第二步: 读取我们刚写的配置文件(共享配置文件)的属性。把user-service微服务项目的config目录的PatternProperties类,修改为如下
- package cn.itcast.user.config;
-
- import lombok.Data;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
-
- @Component
- @Data
- @ConfigurationProperties(prefix = "pattern") //配置属性前缀名
- public class PatternProperties {
- private String dateformat;
- private String envSharedValue;
- }
第三步: 为方便直观的展示是否读取到 '共享配置文件' 的配置,我们在user-service微服务项目的web目录的UserController类,修改为如下
- package cn.itcast.user.web;
-
- import cn.itcast.user.config.PatternProperties;
- import cn.itcast.user.pojo.User;
- import cn.itcast.user.service.UserService;
- import lombok.extern.slf4j.Slf4j;
- import org.checkerframework.checker.units.qual.A;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.cloud.context.config.annotation.RefreshScope;
- import org.springframework.web.bind.annotation.*;
-
- import java.time.LocalDateTime;
- import java.time.format.DateTimeFormatter;
-
- @Slf4j
- @RestController
- @RequestMapping("/user")
- //@RefreshScope
- public class UserController {
-
- @Autowired
- private UserService userService;
-
- @Autowired
- private PatternProperties patternProperties;
-
- /**
- * 路径: /user/110
- *
- * @param id 用户id
- * @return 用户
- */
- @GetMapping("/{id}")
- public User queryById(@PathVariable("id") Long id) {
- return userService.queryById(id);
- }
-
- //验证配置拉取是否成功,我们直接在这里去读取拉取过来的配置,如果能拉取就表示验证成功
- // @Value("${pattern.dateformat}")
- // private String dataformat;
-
- @GetMapping("now")
- public String now(){
- return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat()));
- }
-
- @GetMapping("prop")
- public PatternProperties properties(){
- return patternProperties;
- }
-
- }
第四步: 为方便直观的展示是否读取到 '共享配置文件' 的配置,我们在user-service微服务项目的8082端口改成test
第五步: 启动8081和8082端口
访问8081端口

访问8081端口

思考:
对于8081和8082端口的dev环境的实例来说,是能够同时读取到本地配置文件、当前环境的配置文件、共享配置文件。后两者配置文件我们都是在浏览器配置的,其实本身项目代码里有一个配置文件(application.yml)。当本身的yml配置文件跟这俩浏览器配置的冲突了,以谁为准呢
1、本地的application.yml配置文件跟当前环境的配置文件冲突时,当前环境的配置文件(UserService-dev.yaml)优先级更高
2、本地的application.yml配置文件跟共享配置文件冲突时,共享配置文件(UserService.yaml)优先级更高
3、当前环境的配置文件跟共享配置文件冲突时,当前环境的配置文件(UserService-dev.yaml)优先级更高
优先级排序。profile表示环境的意思,可以是dev开发环境,也可以是test测试环境。排序如下:
服务名-profile.yaml > 服务名.yaml > 本地配置
① 搭建MySQL集群并初始化数据库表
②下载解压nacos
③修改集群配置(节点信息)、数据库配置
④分别启动多个nacos节点
⑤nginx反向代理