关闭

SpringCloud微服务配置管理、配置热更新

发表于:2024-8-28 09:28

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:小宋1021    来源:CSDN

  不知道大家会不会有这样的问题:
  ·网关路由在配置文件中写死了,如果变更必须重启微服务
  · 某些业务配置在配置文件中写死了,每次修改都要重启服务
  · 每个微服务都有很多重复的配置,维护成本高
  这些问题都可以通过统一的配置管理器服务解决。而Nacos不仅仅具备注册中心功能,也具备配置管理的功能:
  微服务共享的配置可以统一交给Nacos保存和管理,在Nacos控制台修改配置后,Nacos会将配置变更推送给相关的微服务,并且无需重启即可生效,实现配置热更新。
  网关的路由同样是配置,因此同样可以基于这个功能实现动态路由功能,无需重启网关即可修改路由配置。
  配置共享
  我们可以把微服务共享的配置抽取到Nacos中统一管理,这样就不需要每个微服务都重复配置了。分为两步:
  ·在Nacos中添加共享配置
  · 微服务拉取配置
  添加共享配置
  我们在项目之中会发现有很多的配置是大同小异的,比如jdbc配置、mybatis-plus配置以及knife4j也就是swagger配置,这会显得非常的笨重。
  这些配置我们都是可以抽取出来放到nacos配置中心的,下面就来演示一下如何抽取配置放到nacos配置中心
  首先是jdbc相关配置:
  spring:
    application:
      name: cart-service #微服务名称
    profiles:
      active: dev
    datasource:
      url: jdbc:mysql://101.201.74.55:3306/hm-cart?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: root
      password: 123
    cloud:
        nacos:
          server-addr: 101.201.74.55:8848 # nacos地址
  mybatis-plus:
    configuration:
      default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
    global-config:
      db-config:
        update-strategy: not_null
        id-type: auto
  然后是日志配置:
  logging:
    level:
      com.hmall: debug
    pattern:
      dateformat: HH:mm:ss:SSS
    file:
      path: "logs/${spring.application.name}"
  然后是swagger以及OpenFeign的配置:
  knife4j:
    enable: true
    openapi:
      title: 商城购物车接口文档
      description: "商城购物车接口文档"
      email: zhanghuyi@itcast.cn
      concat: 
      url: https://www.itcast.cn
      version: v1.0.0
      group:
        default:
          group-name: default
          api-rule: package
          api-rule-resources:
            - com.hmall.cart.controller
  feign:
    okhttp:
      enabled: true
  我们在nacos控制台分别添加这些配置。
  首先是jdbc相关配置,在配置管理->配置列表中点击+新建一个配置:
  记得选择yaml文件。
  配置如下:
  spring:
    datasource:
      url: jdbc:mysql://${hm.db.host:101.201.74.55}:${hm.db.port:3306}/${hm.db.database}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: ${hm.db.un:root}
      password: ${hm.db.pw:123}
   
  mybatis-plus:
    configuration:
      default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
    global-config:
      db-config:
        update-strategy: not_null
        id-type: auto
  注意这里的jdbc的相关参数并没有写死,例如:
  - 数据库ip:通过${hm.db.host:101.201.74.55}配置了默认值为101.201.74.55,同时允许通过${hm.db.host}来覆盖默认值。
  - 数据库端口:通过${hm.db.port:3306}配置了默认值为3306,同时允许通过${hm.db.port}来覆盖默认值。
  - 数据库database:可以通过${hm.db.database}来设定,无默认值。
  然后是统一的日志配置,命名为shared-log.yaml,配置内容如下:
  logging:
    level:
      com.hmall: debug
    pattern:
      dateformat: HH:mm:ss:SSS
    file:
      path: "logs/${spring.application.name}"
  然后是统一的swagger配置,命名为shared-swagger.yaml,配置内容如下:
  knife4j:
    enable: true
    openapi:
      title: ${hm.swagger.title:黑马商城接口文档}
      description: ${hm.swagger.description:黑马商城接口文档}
      email: ${hm.swagger.email:zhanghuyi@itcast.cn}
      concat: ${hm.swagger.concat:虎哥}
      url: https://www.itcast.cn
      version: v1.0.0
      group:
        default:
          group-name: default
          api-rule: package
          api-rule-resources:
            - ${hm.swagger.package}
  注意,这里的swagger相关配置我们没有写死,例如:
  ·title:接口文档标题,我们用了${hm.swagger.title}来代替,将来可以有用户手动指定
  · email:联系人邮箱,我们用了${hm.swagger.email:zhanghuyi@itcast.cn},默认值是zhanghuyi@itcast.cn,同时允许用户利用${hm.swagger.email}来覆盖。
  拉取共享配置
  接下来,我们要在微服务拉取共享配置。将拉取到的共享配置与本地的application.yaml配置合并,完成项目上下文的初始化。
  不过,需要注意的是,读取Nacos配置是SpringCloud上下文(ApplicationContext)初始化时处理的,发生在项目的引导阶段。然后才会初始化SpringBoot上下文,去读取application.yaml。
  也就是说引导阶段,application.yaml文件尚未读取,根本不知道nacos 地址,该如何去加载nacos中的配置文件呢?
  SpringCloud在初始化上下文的时候会先读取一个名为bootstrap.yaml(或者bootstrap.properties)的文件,如果我们将nacos地址配置到bootstrap.yaml中,那么在项目引导阶段就可以读取nacos中的配置了。
  因此,微服务整合Nacos配置管理的步骤如下:
  1)引入依赖:
  在模块引入依赖:
    <!--nacos配置管理-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <!--读取bootstrap文件-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
  2)新建bootstrap.yaml
  在该模块中的resources目录新建一个bootstrap.yaml文件:
  内容如下:
  spring:
    application:
      name: cart-service # 服务名称
    profiles:
      active: dev
    cloud:
      nacos:
        server-addr: 101.201.74.55 # nacos地址
        config:
          file-extension: yaml # 文件后缀名
          shared-configs: # 共享配置
            - dataId: shared-jdbc.yaml # 共享mybatis配置
            - dataId: shared-log.yaml # 共享日志配置
            - dataId: shared-swagger.yaml # 共享日志配置
  3)修改application.yaml
  由于一些配置挪到了bootstrap.yaml,因此application.yaml需要修改为:
  server:
    port: 8082
  feign:
    okhttp:
      enabled: true # 开启OKHttp连接池支持
  hm:
    swagger:
      title: 购物车服务接口文档
      package: com.hmall.cart.controller
    db:
      database: hm-cart
  重启服务,发现所有配置都生效了。
  配置热更新
  配置热更新:当修改配置文件的配置时,微服务无需重启即可配置生效。
  前提条件:
  1.nacos中要有一个与微服务名有关的配置文件,格式为:[服务名]-[spring.active.profile].[后缀名]
  2.微服务中要以特定方式读取需要热更新的配置属性
  有很多的业务相关参数,将来可能会根据实际情况临时调整。例如购物车业务,购物车数量有一个上限,默认是10,对应代码如下:
      private void checkCartsFull(Long userId) {
          int count = lambdaQuery().eq(Cart::getUserId, userId).count();
          if (count >= 10) {
              throw new BizIllegalException(StrUtil.format("用户购物车课程不能超过{}", 10));
          }
      }
  现在这里购物车是写死的固定值,我们应该将其配置在配置文件中,方便后期修改。
  但现在的问题是,即便写在配置文件中,修改了配置还是需要重新打包、重启服务才能生效。能不能不用重启,直接生效呢?
  这就要用到Nacos的配置热更新能力了,分为两步:
  ·在Nacos中添加配置
  · 在微服务读取配置
  配置热更新
  我们在微服务中读取配置,实现配置热更新。
  在cart-service中新建一个属性读取类:
  代码如下:
  package com.hmall.cart.config;

  import io.swagger.models.auth.In;
  import lombok.Data;
  import org.springframework.boot.context.properties.ConfigurationProperties;
  import org.springframework.stereotype.Component;
   
  @Data
  @Component
  @ConfigurationProperties(prefix = "hm.cart")
  public class CartProperties {
      private Integer maxItems;
  }
  接着,在业务中使用该属性加载类:
  private final CartProperties cartProperties;

      private void checkCartsFull(Long userId) {
          int count = lambdaQuery().eq(Cart::getUserId, userId).count();
          if (count >= cartProperties.getMaxItems()) {
              throw new BizIllegalException(StrUtil.format("用户购物车课程不能超过{}", cartProperties.getMaxItems()));
          }
      }
  添加配置到Nacos
  首先,我们在nacos中添加一个配置文件,将购物车的上限数量添加到配置中:
  注意文件的dataId格式:
  [服务名]-[spring.active.profile].[后缀名]
  文件名称由三部分组成:
  ·服务名:我们是购物车服务,所以是cart-service
  · spring.active.profile:就是spring boot中的spring.active.profile,可以省略,则所有profile共享该配置
  · 后缀名:例如yaml
  这里我们直接使用cart-service.yaml这个名称,则不管是dev还是local环境都可以共享该配置。
  配置内容如下:
  hm:
    cart:
      maxAmount: 1 # 购物车商品数量上限
  提交配置,在控制台能看到新添加的配置:
  无需重启立刻生效。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2024软件测试行业从业人员调查问卷》,您的见解,行业的声音!

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号