springcloud之集成nacos config

写在前面

源码

本文看下如下集成nacos config组件。

1:常见配置方式分析

我们先来看下常见的配置方式都有哪些,以及其有什么优点和缺点。

  • 硬编码

    优点:
    hardcode,除了开发的时候快些,爽一下,有个屁优点
    缺点:
    配置和业务耦合,无法做到职责分离
    灵活度低
    修改配置需要修改代码,并重启应用,无法做到运行期灵活变更,对业务影响大,开发人员工作量大

  • 本地配置文件

    优点:
    配置和业务解耦
    缺点:
    灵活度低
    无法做到运行期零或变更,修改配置需要重启程序
    当修改文件较多时,开发人员修改配置文件工作量大,且容易出错

  • -D环境变量

    优点:
    配置和业务解耦
    优点:
    灵活度低
    无法做到运行期灵活变更,修改配置需要重启应用
    安全性低,容易泄露密码等敏感信息
    当应用较多时,修改的成本比较高,且容易出错
    无法进行版本维护,无法快读回滚到某历史版本

  • 数据库

    优点:
    配置和业务解耦
    缺点:
    灵活度低
    无法进行版本维护,无法快读回滚到某历史版本
    高并发场景下,可能将数据库打崩,因此需要时刻关注数据库的性能指标

以上传统配置方式存在的问题,配置中心可解,配置中心方式分析如下:

复制代码
缺点:
    需要引入额外的组件,增加运维成本
优点:
    灵活度高
    通过动态变更的推送可实现运行期动态修改,某些场景下无需重启
    安全性高,通过权限控制提高安全性
    版本管理,实现快速回滚到历史版本
    统一管理配置文件,修改成本低

可参考下面几张图:

2:基于nacos config配置实战

我们以改造custom模块为例来作为实战内容,看下配置项动态更新,首先在custom模块引入依赖:

xml 复制代码
<!-- 添加Nacos Config配置项 -->
<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>

创建bootstrap.yml(springboot中该配置文件加载优先级最高,保证最先加载)配置配置中心相关信息,如下:

复制代码
spring:
  # 必须把name属性从application.yml迁移过来,否则无法动态刷新
  application:
    name: coupon-customer-serv-config
  cloud:
    nacos:
      config:
        # nacos config服务器的地址
        server-addr: 192.168.10.99:8868
        file-extension: yml
        # prefix: 文件名前缀,默认是spring.application.name
        # 如果没有指定命令空间,则默认命令空间为PUBLIC
        namespace: dev
        # 如果没有配置Group,则默认值为DEFAULT_GROUP
        group: DEFAULT_GROUP
        # 从Nacos读取配置项的超时时间
        timeout: 5000
        # 长轮询超时时间
        config-long-poll-timeout: 10000
        # 轮询的重试时间
        config-retry-time: 2000
        # 长轮询最大重试次数
        max-retry: 3
        # 开启监听和自动刷新
        refresh-enabled: true
        # Nacos的扩展配置项,数字越大优先级越高
        extension-configs:
          - dataId: redis-config.yml
            group: EXT_GROUP
            # 动态刷新
            refresh: true
          - dataId: rabbitmq-config.yml
            group: EXT_GROUP
            refresh: true

extension-configs中是设置其他的配置文件,如配置各种三方组件连接信息的配置文件,这里是redis-config.yml和rabbitmq-config.yml。然后,我们点击页面右上角的➕符号创建三个配置文件,coupon-customer-serv.yml(默认分组)、redis-config.yml(EXT_GROUP 分组)和 rabbitmq-config.yml(EXT_GROUP 分组),创建后如下图:

其中coupon-customer-serv-config配置文件内容如下:

复制代码
# 是否发放优惠券的业务开关
disableCouponRequest: false
spring:
#  application:
#    name: coupon-customer-serv
  datasource:
    # mysql数据源
    username: root
    password: root
    url: jdbc:mysql://192.168.10.114:3316/geekbang_coupon_db?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 连接池
    hikari:
      pool-name: GeekbangCouponHikari
      connection-timeout: 5000
      idle-timeout: 30000
      maximum-pool-size: 10
      minimum-idle: 5
      max-lifetime: 60000
      auto-commit: true

注意这里配置了spring.datasource信息,因此需要将application.yml中的注释掉。disableCouponRequest: false我们来使用其来测试配置动态更新功能。接着在CouponCustomerContrller中注入该属性(防止没有,给默认值false):

复制代码
@Value("${disableCouponRequest:false}")
private Boolean disableCoupon;

修改dongshi.daddy.config.controller.CouponCustomerController#requestCoupon,为如下,增加是否发放优惠券的控制:

java 复制代码
@PostMapping("requestCoupon")
public Coupon requestCoupon(@Valid @RequestBody RequestCoupon request) {
    if (disableCoupon) {
        System.out.println("暂停优惠券发放");
        return null;
    } else {
        System.out.println("优惠券正常发放");
    }
    return customerService.requestCoupon(request);
}

最后需要在在CouponCustomerContrller中添加注解@RefreshScope开启配置动态更新,最后就可以启动服务了:

复制代码
...
2024-01-04 15:52:48.643  INFO 21232 --- [           main] c.a.n.client.config.impl.ClientWorker    : [fixed-192.168.10.99_8868-dev] [subscribe] coupon-customer-serv-config+DEFAULT_GROUP+dev
2024-01-04 15:52:48.643  INFO 21232 --- [           main] c.a.nacos.client.config.impl.CacheData   : [fixed-192.168.10.99_8868-dev] [add-listener] ok, tenant=dev, dataId=coupon-customer-serv-config, group=DEFAULT_GROUP, cnt=1
2024-01-04 15:52:48.644  INFO 21232 --- [           main] c.a.n.client.config.impl.ClientWorker    : [fixed-192.168.10.99_8868-dev] [subscribe] coupon-customer-serv-config.yml+DEFAULT_GROUP+dev
2024-01-04 15:52:48.644  INFO 21232 --- [           main] c.a.nacos.client.config.impl.CacheData   : [fixed-192.168.10.99_8868-dev] [add-listener] ok, tenant=dev, dataId=coupon-customer-serv-config.yml, group=DEFAULT_GROUP, cnt=1

看到以上信息则为成功了,接着我们来测试:

复制代码
http://localhost:20001/coupon-customer/requestCoupon

{
    "userId": 1,
    "couponTemplateId": 2
}

接着通过如下操作修改disableCouponRequest为false:



接着查看后台日志输出:

复制代码
2024-01-04 16:01:27.737  INFO 21632 --- [.10.99_8868-dev] c.a.n.client.config.impl.ClientWorker    : [fixed-192.168.10.99_8868-dev] [data-received] dataId=coupon-customer-serv-config, group=DEFAULT_GROUP, tenant=dev, md5=2c03eb542c19f0231dea5abe524540e5, content=# 是否发放优惠券的业务开关
disableCouponRequest: false
spring:
#  application:
#    name: coupon-customer-serv
 ..., type=yaml

看其中的[data-received]就说明是配置动态更新通知,接着再来请求接口:

复制代码
http://localhost:20001/coupon-customer/requestCoupon

{
    "userId": 1,
    "couponTemplateId": 2
}

写在后面

参考文章列表

相关推荐
jmxwzy4 小时前
Spring全家桶
java·spring·rpc
有来技术5 小时前
Spring Boot 4 + Vue3 企业级多租户 SaaS:从共享 Schema 架构到商业化套餐设计
java·vue.js·spring boot·后端
东东5166 小时前
学院个人信息管理系统 (springboot+vue)
vue.js·spring boot·后端·个人开发·毕设
三水不滴7 小时前
Redis缓存更新策略
数据库·经验分享·redis·笔记·后端·缓存
小邓吖7 小时前
自己做了一个工具网站
前端·分布式·后端·中间件·架构·golang
qq_12498707538 小时前
基于Srpingboot心晴疗愈社平台的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·spring·microsoft·毕业设计·计算机毕业设计
大爱编程♡8 小时前
SpringBoot统一功能处理
java·spring boot·后端
rabbit_pro9 小时前
SpringBoot3使用PostGis+GeoTools整合MybatisPlus
java·spring
好好研究11 小时前
总结SSM设置欢迎页的方式
xml·java·后端·mvc
小马爱打代码11 小时前
Spring Boot:第三方 API 调用的企业级容错设计
java·spring boot·后端