• 实用篇-Nacos配置管理


    Nacos不仅具有注册中心的功能,还具有注册管理的功能

    一、Nacos实现配置管理

    可以使用统一配置管理,来配置更改热更新,整体结构如下

    前提条件: 你已经把上面的 '实用篇-Nacos注册中心' 学完了,并且项目也跟着做了。我们下面会使用到上面的项目。具体操作如下

    第一步: 浏览器访问http://localhost:8848/nacos/index.html,用户名和密码都是nacos,登录进管理面板

    第二步: 在管理面板添加配置

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

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

    二、Nacos微服务配置拉取

    在微服务去获取上面Nacos做出来了的配置文件,步骤如下图

    具体步骤如下

    第一步: 在UserService微服务的pom.xml,添加如下,引入Nacos的配置管理客户端依赖

    1. <dependency>
    2. <groupId>com.alibaba.cloudgroupId>
    3. <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
    4. dependency>

    第二步: 在UserService微服务中的resources目录新建File,文件名是bootstrap.yml。注意bootstrap.yml文件是引导文件,优先级高于application.yml文件。添加如下

    1. spring:
    2. application:
    3. # 服务名称
    4. name: UserService
    5. profiles:
    6. # 环境,dev表示开发环境
    7. active: dev
    8. cloud:
    9. nacos:
    10. # nacos的服务地址
    11. server-addr: localhost:8848
    12. config:
    13. # 我们创建的dev命名空间
    14. namespace: d8ec5ecb-2268-4551-ac2d-f08953292b28
    15. # 文件后缀名
    16. file-extension: yaml

    第三步: 把application.yml中删掉如下。跟刚刚的bootstrap.yml重复的代码给删掉,也就是如果代码重复的话只保留bootstrap.yml的代码,操作后application.yml文件如下

    1. server:
    2. port: 8081
    3. spring:
    4. datasource:
    5. url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    6. username: root
    7. password:
    8. driver-class-name: com.mysql.jdbc.Driver
    9. # # 跨集群部署
    10. # discovery:
    11. # cluster-name: SH # 自定义集群的名字
    12. mybatis:
    13. type-aliases-package: cn.itcast.user.pojo
    14. configuration:
    15. map-underscore-to-camel-case: true
    16. logging:
    17. level:
    18. cn.itcast: debug
    19. pattern:
    20. dateformat: MM-dd HH:mm:ss:SSS
    21. #eureka:
    22. # client:
    23. # service-url:
    24. # # eureka的服务地址。如果有多个的话,逗号隔开。也就是把当前这个user-service微服务注册给哪个Eureka
    25. # defaultZone: http://localhost:8686/eureka

    第四步: 验证UserService微服务有没有拉取到配置文件。在UserService微服务的web目录的UserController类里面添加如下 

    1. //验证配置拉取是否成功,我们直接在这里去读取拉取过来的配置,如果能拉取就表示验证成功
    2. @Value("${pattern.dateformat}")
    3. private String dataformat;
    4. @GetMapping("now")
    5. public String now(){
    6. return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dataformat));
    7. }

    第五步: 测试。重新启动UserService微服务,浏览器访问 http://localhost:8081/user/now

     

    上面我们已经实现了读取Nacos上写的配置文件,但是存在一个问题,如果配置文件修改了那必须重启服务才能生效修改后的配置。

    能不能让Nacos中写的配置文件实现热更新呢,也就是实时生效,不需要重新启动微服务

    三、配置热更新

    方式①

    Nacos中的配置文件变更后,微服务无需重启就可以感知,实现的方式有两种,如下:

    第一种: 在@Value注入的变量所在类(也就是我们上面的UserController类)上添加注解@RefreshScope

    第一种的具体操作如下

    第一步: 在UserService微服务的web目录的UserController类添加如下,并重新启动UserService微服务的实例

    第二步: 修改浏览器上写的配置文件,修改为如下,点击发布

    1. pattern:
    2. dateformat: yyyy.MM.dd HH:mm:ss

    第三步: 查看是否实现热更新,浏览器访问,可以看到,直接访问的是更新后的配置,而无需重启服务

    方式②

    第二种配置热更新方式是: 使用@ConfigurationProperties注解

    第一步:在user-service项目下创建config/PatternProperties类

    1. package cn.itcast.user.config;
    2. import lombok.Data;
    3. import org.springframework.boot.context.properties.ConfigurationProperties;
    4. import org.springframework.stereotype.Component;
    5. @Component
    6. @Data
    7. @ConfigurationProperties(prefix = "pattern") //配置属性前缀名
    8. public class PatternProperties {
    9. private String dateformat;
    10. }

     第二步: 在user-service微服务项目的web目录的UserController类修改为如下

    1. package cn.itcast.user.web;
    2. import cn.itcast.user.config.PatternProperties;
    3. import cn.itcast.user.pojo.User;
    4. import cn.itcast.user.service.UserService;
    5. import lombok.extern.slf4j.Slf4j;
    6. import org.checkerframework.checker.units.qual.A;
    7. import org.springframework.beans.factory.annotation.Autowired;
    8. import org.springframework.beans.factory.annotation.Value;
    9. import org.springframework.cloud.context.config.annotation.RefreshScope;
    10. import org.springframework.web.bind.annotation.*;
    11. import java.time.LocalDateTime;
    12. import java.time.format.DateTimeFormatter;
    13. @Slf4j
    14. @RestController
    15. @RequestMapping("/user")
    16. //@RefreshScope
    17. public class UserController {
    18. @Autowired
    19. private UserService userService;
    20. @Autowired
    21. private PatternProperties patternProperties;
    22. /**
    23. * 路径: /user/110
    24. *
    25. * @param id 用户id
    26. * @return 用户
    27. */
    28. @GetMapping("/{id}")
    29. public User queryById(@PathVariable("id") Long id) {
    30. return userService.queryById(id);
    31. }
    32. //验证配置拉取是否成功,我们直接在这里去读取拉取过来的配置,如果能拉取就表示验证成功
    33. // @Value("${pattern.dateformat}")
    34. // private String dataformat;
    35. @GetMapping("now")
    36. public String now(){
    37. return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat()));
    38. }
    39. }

    第三步: 测试。重新启动UserService微服务,先访问一下能不能拿到配置文件里面的数据

    修改nacos配置如下

     点击发布,不重启项目,直接访问

     总结

    两种微服务热更新的方式,总结

    • 第一种: 通过@Value注解注入,结合@RefreshScope注解来刷新
    • 第二种: 通过@ConfigurationProperties注解注入,实现刷新

    注意事项:

    • 不是所有的配置都适合放到配置中心(nacos不仅是注册中心,还是配置中心),维护起来比较困难
    • 建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置

    四、多环境配置共享

    场景: 有一个配置属性,该配置属性在开发、生产、测试等环境下的值是一样的,我们就不用在每个配置文件里面都写一份,而是使用多环境配置共享。简单说就是把配置写在一个地方,不管环境怎么变,配置都能被加载。下面将进入学习

    微服务启动时会从nacos里自动读取两种配置文件。如下

    注意除了这两种nacos '线上配置文件' ,微服务还有自身的application.yml配置文件(叫 '本地配置文件' )。所以微服务启动时会自动读取这三种

    (1)、当微服务启动时,会根据环境加载对应的配置文件

    • [spring.application.name]-[spring.profiles.active].yaml,例如: userservice-dev.yaml。格式: 服务名-环境.yaml

    (2)、当微服务启动时,必然会加载这类的配置文件。我们可以把多环境共享配置写入这个文件

    • [spring.application.name].yaml,例如: userservice.yaml。格式: 服务名.yaml

    (3)、微服务自身的application.yml配置文件(叫 '本地配置文件' )

    案例如下

    第一步: 在浏览器的nacos管理界面添加一个新的配置文件,作为我们下面要学的多环境配置文件

    第二步: 读取我们刚写的配置文件(共享配置文件)的属性。把user-service微服务项目的config目录的PatternProperties类,修改为如下

    1. package cn.itcast.user.config;
    2. import lombok.Data;
    3. import org.springframework.boot.context.properties.ConfigurationProperties;
    4. import org.springframework.stereotype.Component;
    5. @Component
    6. @Data
    7. @ConfigurationProperties(prefix = "pattern") //配置属性前缀名
    8. public class PatternProperties {
    9. private String dateformat;
    10. private String envSharedValue;
    11. }

    第三步: 为方便直观的展示是否读取到 '共享配置文件' 的配置,我们在user-service微服务项目的web目录的UserController类,修改为如下 

    1. package cn.itcast.user.web;
    2. import cn.itcast.user.config.PatternProperties;
    3. import cn.itcast.user.pojo.User;
    4. import cn.itcast.user.service.UserService;
    5. import lombok.extern.slf4j.Slf4j;
    6. import org.checkerframework.checker.units.qual.A;
    7. import org.springframework.beans.factory.annotation.Autowired;
    8. import org.springframework.beans.factory.annotation.Value;
    9. import org.springframework.cloud.context.config.annotation.RefreshScope;
    10. import org.springframework.web.bind.annotation.*;
    11. import java.time.LocalDateTime;
    12. import java.time.format.DateTimeFormatter;
    13. @Slf4j
    14. @RestController
    15. @RequestMapping("/user")
    16. //@RefreshScope
    17. public class UserController {
    18. @Autowired
    19. private UserService userService;
    20. @Autowired
    21. private PatternProperties patternProperties;
    22. /**
    23. * 路径: /user/110
    24. *
    25. * @param id 用户id
    26. * @return 用户
    27. */
    28. @GetMapping("/{id}")
    29. public User queryById(@PathVariable("id") Long id) {
    30. return userService.queryById(id);
    31. }
    32. //验证配置拉取是否成功,我们直接在这里去读取拉取过来的配置,如果能拉取就表示验证成功
    33. // @Value("${pattern.dateformat}")
    34. // private String dataformat;
    35. @GetMapping("now")
    36. public String now(){
    37. return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat()));
    38. }
    39. @GetMapping("prop")
    40. public PatternProperties properties(){
    41. return patternProperties;
    42. }
    43. }

    第四步: 为方便直观的展示是否读取到 '共享配置文件' 的配置,我们在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 > 本地配置

    五、Nacos集群搭建

    ① 搭建MySQL集群并初始化数据库表
    ②下载解压nacos
    ③修改集群配置(节点信息)、数据库配置
    ④分别启动多个nacos节点
    ⑤nginx反向代理

  • 相关阅读:
    JavaSE_第7章 面向对象基础(下)
    2023国赛数学建模C题模型代码
    【机器学习网络】BP神经网络与深度学习-6 深度神经网络(deep neural Networks DNN)
    不能一棍子敲死刚诞生不久的USB-C,虽然它有时确实很惹人厌
    阿里云服务器计算型、通用型、内存型各实例计算、存储等性能介绍
    “熊猫视图”.Net图形控件功能介绍 [五]:视图平移
    使用Apache Flink 和 Apache Hudi 创建低延迟数据湖管道
    职场PUA:为什么你就不能逼自己一把呢?
    Java进阶03 IO基础
    电竞游戏行业有哪些媒体资源?活动发布会如何宣传?
  • 原文地址:https://blog.csdn.net/m0_63732435/article/details/134091881