写在前面
源码 。
本文看下如下集成nacos config组件。
1:常见配置方式分析
我们先来看下常见的配置方式都有哪些,以及其有什么优点和缺点。
- 硬编码
优点:hardcode,除了开发的时候快些,爽一下,有个屁优点
缺点:配置和业务耦合,无法做到职责分离灵活度低修改配置需要修改代码,并重启应用,无法做到运行期灵活变更,对业务影响大,开发人员工作量大
- 本地配置文件
优点:配置和业务解耦
缺点:灵活度低无法做到运行期零或变更,修改配置需要重启程序当修改文件较多时,开发人员修改配置文件工作量大,且容易出错
- -D环境变量
优点:配置和业务解耦
优点:灵活度低无法做到运行期灵活变更,修改配置需要重启应用安全性低,容易泄露密码等敏感信息当应用较多时,修改的成本比较高,且容易出错无法进行版本维护,无法快读回滚到某历史版本
- 数据库
优点:配置和业务解耦
缺点:灵活度低无法进行版本维护,无法快读回滚到某历史版本高并发场景下,可能将数据库打崩,因此需要时刻关注数据库的性能指标
以上传统配置方式存在的问题,配置中心可解,配置中心方式分析如下:
缺点:需要引入额外的组件,增加运维成本
优点:灵活度高通过动态变更的推送可实现运行期动态修改,某些场景下无需重启安全性高,通过权限控制提高安全性版本管理,实现快速回滚到历史版本统一管理配置文件,修改成本低
可参考下面几张图:
2:基于nacos config配置实战
我们以改造custom模块为例来作为实战内容,看下配置项动态更新,首先在custom模块引入依赖:
<!-- 添加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-configcloud:nacos:config:# nacos config服务器的地址server-addr: 192.168.10.99:8868file-extension: yml# prefix: 文件名前缀,默认是spring.application.name# 如果没有指定命令空间,则默认命令空间为PUBLICnamespace: dev# 如果没有配置Group,则默认值为DEFAULT_GROUPgroup: 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.ymlgroup: EXT_GROUP# 动态刷新refresh: true- dataId: rabbitmq-config.ymlgroup: EXT_GROUPrefresh: 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-servdatasource:# mysql数据源username: rootpassword: rooturl: jdbc:mysql://192.168.10.114:3316/geekbang_coupon_db?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTCtype: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driver# 连接池hikari:pool-name: GeekbangCouponHikariconnection-timeout: 5000idle-timeout: 30000maximum-pool-size: 10minimum-idle: 5max-lifetime: 60000auto-commit: true
注意这里配置了spring.datasource信息,因此需要将application.yml中的注释掉。disableCouponRequest: false
我们来使用其来测试配置动态更新功能。接着在CouponCustomerContrller中注入该属性(防止没有,给默认值false)
:
@Value("${disableCouponRequest:false}")
private Boolean disableCoupon;
修改dongshi.daddy.config.controller.CouponCustomerController#requestCoupon
,为如下,增加是否发放优惠券的控制:
@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
}