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
}

写在后面

参考文章列表

相关推荐
苏-言12 分钟前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
草莓base32 分钟前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring
Ljw...1 小时前
表的增删改查(MySQL)
数据库·后端·mysql·表的增删查改
编程重生之路1 小时前
Springboot启动异常 错误: 找不到或无法加载主类 xxx.Application异常
java·spring boot·后端
薯条不要番茄酱1 小时前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
冰帝海岸7 小时前
01-spring security认证笔记
java·笔记·spring
没书读了8 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
qq_17448285759 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
锅包肉的九珍9 小时前
Scala的Array数组
开发语言·后端·scala
心仪悦悦9 小时前
Scala的Array(2)
开发语言·后端·scala