配置中心 - 不用改代码就能改配置

一、配置管理的烦恼

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

场景1:数据库密码改了

以前:每个微服务都连数据库,密码改了得:

  1. 改user-service的application.yml
  2. 改order-service的application.yml
  3. 改product-service的application.yml
  4. 每个服务都得重启
  5. 生产环境还得走发布流程

太麻烦了!

场景2:双11活动配置

活动期间:

  • 商品打8折
  • 满200减30
  • 限时抢购

以前:改配置 -> 打包 -> 发布 -> 重启
活动都结束了,服务还没重启完!

场景3:不同环境不同配置

  • 开发环境:用本地数据库
  • 测试环境:用测试数据库
  • 生产环境:用生产数据库

以前:打包时切换profile,容易出错!

二、配置中心是啥?

就像公司的公告板

  • 所有配置都写在公告板上
  • 员工(微服务)每天上班先看公告板
  • 公告板改了,员工自动知道
  • 不用每个人挨个通知

配置中心的好处:

  1. 一处改,处处生效
  2. 热更新:不用重启服务
  3. 版本管理:可以回滚
  4. 权限控制:谁能改配置
  5. 环境隔离:开发、测试、生产分开

三、为啥选Nacos配置中心?

配置中心优点缺点适用场景
Spring Cloud ConfigSpring亲儿子,集成好需要配合Git,功能简单简单项目
Apollo功能强大,界面好部署复杂,太重大厂,复杂项目
Nacos配置+注册一体,轻量功能不如Apollo全中小项目,Spring Cloud Alibaba
Consul配置+注册+健康检查对Spring Cloud支持一般Go项目多

咱们选Nacos,因为

  1. 已经用Nacos做注册中心了
  2. 配置管理功能够用
  3. 跟Spring Cloud Alibaba集成好
  4. 部署简单

四、Nacos配置中心原理

1. 拉模式(Pull)

// 服务启动时1.Nacos拉取配置2.加载到Spring环境3.创建Bean// 定时任务30秒拉取一次,检查配置变没变

2. 推模式(Push)

1.配置改了,Nacos通知服务2.服务收到通知,拉取新配置3.刷新Bean@RefreshScope

3. 配置结构

Data ID: user-service-dev.yaml Group: DEFAULT_GROUP Namespace: dev 相当于: 文件位置:dev/DEFAULT_GROUP/user-service-dev.yaml

五、开整!把配置挪到Nacos

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

步骤1:Nacos控制台加配置

  1. 访问http://localhost:8848/nacos
  2. 左边菜单:配置管理->配置列表
  3. 点右上角:+

配置1:用户服务公共配置

Data ID: user-service.yaml Group: DEFAULT_GROUP 配置格式: YAML 配置内容: server: port: 8081 spring: datasource: url: jdbc:mysql://localhost:3306/user_db?useSSL=false username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8

配置2:用户服务开发环境

Data ID: user-service-dev.yaml Group: DEFAULT_GROUP 配置内容: spring: datasource: url: jdbc:mysql://localhost:3306/user_db_dev?useSSL=false logging: level: com.example: debug

配置3:用户服务生产环境

Data ID: user-service-prod.yaml Group: DEFAULT_GROUP 配置内容: spring: datasource: url: jdbc:mysql://prod-mysql:3306/user_db?useSSL=false password: ${DB_PASSWORD:强密码} logging: level: com.example: info

步骤2:改造user-service

1. 加依赖

pom.xml

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- 配置刷新 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency>
2. 加配置文件

bootstrap.yml重点!必须用这个文件名):

spring:application:name:user-service# 服务名,一定要有!cloud:nacos:config:server-addr:localhost:8848# Nacos地址file-extension:yaml# 配置文件格式group:DEFAULT_GROUP# 分组,默认就是这个namespace:dev# 命名空间,对应环境# 配置内容(重要!)# 1. 先加载user-service.yaml(公共配置)# 2. 再加载user-service-dev.yaml(环境配置)# 3. 最后加载本地application.ymlextension-configs:-data-id:user-service.yamlgroup:DEFAULT_GROUPrefresh:true# 是否刷新-data-id:user-service-${spring.profiles.active}.yamlgroup:DEFAULT_GROUPrefresh:true

application.yml(本地保留少量配置):

# 这里只放本地特有的配置,或者默认值spring:profiles:active:dev# 激活的环境# 本地可以覆盖Nacos的配置# 但建议能放Nacos就放Nacos
3. 测试配置生效
@RestController@RequestMapping("/config")publicclassConfigController{@Value("${server.port}")privateStringport;@Value("${spring.datasource.url}")privateStringdbUrl;@Value("${logging.level.com.example}")privateStringlogLevel;@GetMapping("/show")publicMap<String,String>showConfig(){Map<String,String>config=newHashMap<>();config.put("port",port);config.put("dbUrl",dbUrl);config.put("logLevel",logLevel);returnconfig;}}

访问http://localhost:8081/config/show,应该显示Nacos里的配置。

六、配置动态刷新(热更新)

场景:双11改折扣

商品服务有个折扣配置:

# 在Nacos配置sale:discount:0.8# 8折

步骤1:创建配置Bean

@Component@ConfigurationProperties(prefix="sale")@RefreshScope// 重点!支持动态刷新@DatapublicclassSaleConfig{privateDoublediscount=1.0;// 默认不打折privateIntegerfullReduction=0;// 满减privateBooleanflashSale=false;// 是否限时抢购}

步骤2:使用配置

@RestController@RequestMapping("/product")publicclassProductController{@AutowiredprivateSaleConfigsaleConfig;@GetMapping("/price/{originalPrice}")publicDoublecalculatePrice(@PathVariableDoubleoriginalPrice){// 动态读取配置returnoriginalPrice*saleConfig.getDiscount();}@GetMapping("/config")publicSaleConfiggetConfig(){returnsaleConfig;}}

步骤3:测试热更新

  1. 启动服务,访问http://localhost:8083/product/config
  2. 看到折扣是0.8(8折)
  3. 不要重启服务,去Nacos控制台
  4. 修改product-service.yaml
    sale:discount:0.7# 改成7折fullReduction:30# 满200减30
  5. 发布
  6. 刷新页面,配置自动变成7折

七、配置的优先级(重要!)

加载顺序(后加载的覆盖先加载的):

  1. bootstrap.yml(本地,最高优先级)
  2. Nacos扩展配置(extension-configs,按数组顺序)
  3. Nacos共享配置(shared-configs)
  4. Nacos主配置(data-id: ${spring.application.name}.yaml)
  5. application.yml(本地,最低优先级)

示例配置:

spring:cloud:nacos:config:# 1. 先加载 common.yaml(基础配置)extension-configs[0]:data-id:common.yamlgroup:DEFAULT_GROUPrefresh:true# 2. 再加载 middleware.yaml(中间件配置)extension-configs[1]:data-id:middleware.yamlgroup:DEFAULT_GROUPrefresh:true# 3. 加载应用配置#># 4. 最后加载环境配置#>共享配置(所有服务都用)
Data ID: common.yaml 内容: spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 mybatis: configuration: map-underscore-to-camel-case: true
# 在bootstrap.yml里shared-configs:-data-id:common.yamlgroup:DEFAULT_GROUPrefresh:true

八、多环境配置

方案1:用Namespace(命名空间)

  1. 在Nacos创建命名空间:

    • dev(开发)
    • test(测试)
    • prod(生产)
  2. 每个环境一套配置

  3. 服务启动时指定namespace

spring:cloud:nacos:config:namespace:dev# 开发环境# 或者用环境变量namespace:${NACOS_NAMESPACE:dev}

方案2:用Group(分组)

spring:profiles:active:devcloud:nacos:config:group:${spring.profiles.active}# 根据环境选分组

方案3:用Data ID后缀

Data ID格式:${spring.application.name}-${环境}.yaml 例如: - user-service-dev.yaml - user-service-test.yaml - user-service-prod.yaml
spring:cloud:nacos:config:# 自动拼接环境name:${spring.application.name}file-extension:yaml# Nacos会找:user-service-dev.yaml

九、敏感配置加密

场景:数据库密码不能明文存

步骤1:加Jasypt依赖

<dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.5</version></dependency>

步骤2:生成加密值

@SpringBootApplicationpublicclassTestApp{publicstaticvoidmain(String[]args){StandardPBEStringEncryptorencryptor=newStandardPBEStringEncryptor();encryptor.setPassword("mySecretKey");// 加密密钥Stringencrypted=encryptor.encrypt("123456");System.out.println("加密后: "+encrypted);// 输出:g8N5jJYVWp9jF6Bz8n4K7Q==}}

步骤3:Nacos配置用加密值

spring:datasource:password:ENC(g8N5jJYVWp9jF6Bz8n4K7Q==)# 用ENC()包裹

步骤4:启动时传入密钥

# 方式1:启动参数java -jar app.jar --jasypt.encryptor.password=mySecretKey# 方式2:环境变量exportJASYPT_ENCRYPTOR_PASSWORD=mySecretKey java -jar app.jar# 方式3:配置文件(不安全)# jasypt.encryptor.password=mySecretKey

十、配置的最佳实践

1. 配置分类存放

Nacos配置: ├── common.yaml(所有服务共享) ├── middleware.yaml(中间件配置) ├── user-service.yaml(用户服务配置) ├── user-service-dev.yaml(开发环境) └── user-service-prod.yaml(生产环境)

2. 配置版本管理

  • 每次修改前备份
  • 使用配置历史功能
  • 重要配置变更要评审

3. 配置监控

@ComponentpublicclassConfigChangeListener{// 监听配置变更@EventListenerpublicvoidhandleRefresh(RefreshScopeRefreshedEventevent){System.out.println("配置已刷新: "+newDate());// 发送通知// 记录日志// 刷新缓存}}

4. 配置回滚

  1. Nacos控制台 -> 配置详情 -> 历史版本
  2. 选择要回滚的版本
  3. 回滚
  4. 所有服务自动生效

5. 配置检查

@RestController@RequestMapping("/actuator")publicclassConfigCheckController{@AutowiredprivateEnvironmentenvironment;@GetMapping("/config-check")publicMap<String,Object>checkConfig(){Map<String,Object>result=newHashMap<>();// 检查必要配置String[]requiredProps={"spring.datasource.url","spring.datasource.username","spring.redis.host"};for(Stringprop:requiredProps){Stringvalue=environment.getProperty(prop);result.put(prop,value!=null?"OK":"MISSING");}returnresult;}}

十一、常见问题解决

1. 配置不生效

原因:加载顺序问题
解决

# bootstrap.ymlspring:cloud:nacos:config:# 明确指定加载哪些配置extension-configs[0]:data-id:common.yamlgroup:DEFAULT_GROUPrefresh:trueextension-configs[1]:data-id:${spring.application.name}.yamlgroup:DEFAULT_GROUPrefresh:true

2. 动态刷新不生效

原因

  1. 没加@RefreshScope
  2. 配置没在Nacos里
  3. 没加spring-cloud-starter-bootstrap

解决

// 1. 类上加@RefreshScope// 2. 确保配置在Nacos// 3. 检查依赖

3. 配置冲突

现象:本地配置覆盖了Nacos配置
解决

# application.yml里尽量少放配置# 只放本地测试需要的spring:cloud:nacos:config:override-none:true# 本地不覆盖远程override-system-properties:false# 系统属性不覆盖

4. 启动报错:找不到配置

原因:Nacos连接失败或配置不存在
解决

spring:cloud:nacos:config:# 允许配置不存在refresh-enabled:true# 设置超时timeout:3000# 失败重试max-retry:3retry-interval:1000

十二、实际项目配置示例

完整bootstrap.yml

spring:application:name:user-serviceprofiles:active:${PROFILE:dev}# 从环境变量读取cloud:nacos:config:server-addr:${NACOS_HOST:localhost}:${NACOS_PORT:8848}username:${NACOS_USERNAME:nacos}password:${NACOS_PASSWORD:nacos}namespace:${NACOS_NAMESPACE:dev}file-extension:yamlrefresh-enabled:true# 共享配置(所有服务)shared-configs:-data-id:common.yamlgroup:COMMON_GROUPrefresh:true-data-id:datasource.yamlgroup:MIDDLEWARE_GROUPrefresh:true-data-id:redis.yamlgroup:MIDDLEWARE_GROUPrefresh:true# 扩展配置(本服务)extension-configs:-data-id:${spring.application.name}.yamlgroup:DEFAULT_GROUPrefresh:true-data-id:${spring.application.name}-${spring.profiles.active}.yamlgroup:DEFAULT_GROUPrefresh:true# 本地默认值(开发环境方便)server:port:8081logging:level:root:infocom.example:debug

Nacos配置文件示例

common.yaml(所有服务共享):

# 应用通用配置app:version:1.0.0env:${spring.profiles.active}# 日期时间格式spring:jackson:date-format:yyyy-MM-dd HH:mm:sstime-zone:GMT+8default-property-inclusion:non_null# 文件上传servlet:multipart:max-file-size:10MBmax-request-size:10MB# 日志logging:pattern:console:"%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

datasource.yaml(数据库配置):

spring:datasource:type:com.zaxxer.hikari.HikariDataSourcedriver-class-name:com.mysql.cj.jdbc.Driverhikari:minimum-idle:5maximum-pool-size:20idle-timeout:30000max-lifetime:1800000connection-timeout:30000connection-test-query:SELECT 1# Mybatismybatis:configuration:map-underscore-to-camel-case:truelog-impl:org.apache.ibatis.logging.stdout.StdOutImpl

十三、今儿个总结

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

学会了啥?

  1. ✅ 配置中心的作用(一处改,处处生效)
  2. ✅ Nacos配置中心的使用
  3. ✅ 配置文件加载顺序
  4. ✅ 动态刷新(@RefreshScope)
  5. ✅ 多环境配置
  6. ✅ 配置加密
  7. ✅ 最佳实践

关键点

  1. bootstrap.yml优先加载
  2. @RefreshScope支持热更新
  3. 命名空间隔离环境
  4. 配置优先级要清楚
  5. 敏感信息要加密

十四、明儿个学啥?

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

明天咱学分布式事务

  • 用户下单,扣库存,这两步要一起成功或一起失败
  • 跨服务的事务怎么保证一致性
  • Seata是啥,咋用
  • 分布式事务的几种方案

明天咱解决钱不能算错的问题!💰

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1153767.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何快速实现Figma界面全面中文化:新手必备完整指南

如何快速实现Figma界面全面中文化&#xff1a;新手必备完整指南 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma复杂的英文界面而苦恼吗&#xff1f;每次操作都要反复查阅词…

【Java函数式编程进阶】:掌握Lambda默认参数重载的3种高阶技巧

第一章&#xff1a;Lambda默认参数重载在现代编程语言中&#xff0c;Lambda 表达式已成为函数式编程的重要组成部分。尽管 Lambda 本身不直接支持方法重载&#xff0c;但通过巧妙使用默认参数&#xff0c;可以在一定程度上模拟重载行为&#xff0c;提升代码的灵活性和可读性。默…

Source Han Serif CN字体创意应用全攻略:7大秘籍提升中文设计品质

Source Han Serif CN字体创意应用全攻略&#xff1a;7大秘籍提升中文设计品质 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还在为中文排版效果不佳而烦恼吗&#xff1f;Source Han …

交错数组并发访问陷阱(90%开发者忽略的内存泄漏风险)

第一章&#xff1a;交错数组并发访问陷阱&#xff08;90%开发者忽略的内存泄漏风险&#xff09;在高并发系统中&#xff0c;交错数组&#xff08;Jagged Array&#xff09;常被用于存储动态结构数据。然而&#xff0c;当多个协程或线程同时读写交错数组的不同层级时&#xff0c…

内存占用暴增?可能是你没用对内联数组,9大优化技巧速看

第一章&#xff1a;内存占用暴增&#xff1f;内联数组为何成关键突破口在现代高性能系统开发中&#xff0c;内存占用异常往往是性能瓶颈的根源。当应用频繁进行动态内存分配时&#xff0c;堆内存碎片化和GC压力会显著上升&#xff0c;导致服务响应延迟增加。此时&#xff0c;内…

Windows热键冲突排查终极宝典:3分钟找回被抢占的快捷键

Windows热键冲突排查终极宝典&#xff1a;3分钟找回被抢占的快捷键 【免费下载链接】hotkey-detective A small program for investigating stolen hotkeys under Windows 8 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective 你是否曾经在关键时刻按下Ctr…

Edge AI骨骼检测方案:本地端+云端协同,成本直降70%

Edge AI骨骼检测方案&#xff1a;本地端云端协同&#xff0c;成本直降70% 1. 为什么需要边缘计算云计算的协同方案&#xff1f; 智能硬件厂商在开发姿势识别产品时&#xff0c;常常面临一个两难选择&#xff1a;如果全部计算都在设备端&#xff08;如摄像头、智能手环等&…

Switch系统个性化配置全攻略:从功能解锁到视觉焕新

Switch系统个性化配置全攻略&#xff1a;从功能解锁到视觉焕新 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 还在为Switch系统千篇一律的界面而烦恼吗&#xff1f;想让你的游戏主机既好用…

Qt悬停移动事件全解析

hoverMoveEvent(QGraphicsSceneHoverEvent *event) 是 Qt 框架中 QGraphicsItem 类的一个虚函数&#xff0c;用于处理鼠标在图形项&#xff08;graphics item&#xff09;上悬停并移动时的事件。当你重写&#xff08;override&#xff09;这个函数时&#xff0c;通常是为了在用…

Keyboard Chatter Blocker终极解决方案:彻底告别机械键盘连击烦恼

Keyboard Chatter Blocker终极解决方案&#xff1a;彻底告别机械键盘连击烦恼 【免费下载链接】KeyboardChatterBlocker A handy quick tool for blocking mechanical keyboard chatter. 项目地址: https://gitcode.com/gh_mirrors/ke/KeyboardChatterBlocker 还在为机械…

手势识别开发指南:MediaPipe Hands高级技巧

手势识别开发指南&#xff1a;MediaPipe Hands高级技巧 1. 引言&#xff1a;AI 手势识别与追踪的工程价值 随着人机交互技术的不断演进&#xff0c;手势识别正逐步成为智能设备、虚拟现实、增强现实和智能家居等场景中的核心感知能力。传统触摸或语音交互在特定环境下存在局限…

2026趋势:测试中的元宇宙应用

元宇宙重塑测试疆界 随着元宇宙技术从概念走向落地&#xff0c;2026年将成为软件测试领域的分水岭。元宇宙——一个融合虚拟现实&#xff08;VR&#xff09;、增强现实&#xff08;AR&#xff09;、人工智能&#xff08;AI&#xff09;和区块链的沉浸式数字空间——正彻底改变…

强力文档下载神器kill-doc:彻底告别繁琐下载流程

强力文档下载神器kill-doc&#xff1a;彻底告别繁琐下载流程 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档&#xff0c;但是相关网站浏览体验不好各种广告&#xff0c;各种登录验证&#xff0c;需要很多步骤才能下载文档&#xff0c;该脚本就是为了解决您…

告别方法重载冗余代码,用Lambda实现默认参数(效率提升80%的秘密)

第一章&#xff1a;告别方法重载冗余代码&#xff0c;认识Lambda默认参数新范式 在现代编程实践中&#xff0c;方法重载虽然提供了灵活性&#xff0c;但也常常导致大量重复且难以维护的代码。随着语言特性的演进&#xff0c;Lambda表达式结合默认参数机制正逐步成为简化函数接口…

Z-Image-ComfyUI开箱即用:0配置云端GPU,小白秒变AI画家

Z-Image-ComfyUI开箱即用&#xff1a;0配置云端GPU&#xff0c;小白秒变AI画家 引言&#xff1a;退休教师的AI绘画新体验 张老师退休后一直想学点新东西&#xff0c;最近被朋友圈里的AI绘画作品吸引。但当她尝试自己安装Stable Diffusion时&#xff0c;被复杂的Python环境配置…

AI手势识别部署案例:MediaPipe Hands环境配置

AI手势识别部署案例&#xff1a;MediaPipe Hands环境配置 1. 引言&#xff1a;AI 手势识别与追踪 随着人机交互技术的不断演进&#xff0c;AI手势识别正逐步从实验室走向消费级应用。无论是虚拟现实、智能驾驶&#xff0c;还是远程会议系统&#xff0c;精准的手势感知能力都成…

思源宋体TTF:免费开源的终极中文字体解决方案

思源宋体TTF&#xff1a;免费开源的终极中文字体解决方案 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还在为寻找既专业又免费的中文字体而困扰吗&#xff1f;思源宋体TTF格式作为A…

2026毕设ssm+vue交通事故证据交易平台论文+程序

本系统&#xff08;程序源码&#xff09;带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、选题背景 近年来&#xff0c;随着高校毕业设计管理规模的不断扩大&#xff0c;传统纸质或半手工的管理方式已难以满足“题目多、流程长…

骨骼关键点检测避坑指南:小白用云端GPU免踩环境坑

骨骼关键点检测避坑指南&#xff1a;小白用云端GPU免踩环境坑 引言&#xff1a;为什么你的OpenPose总是装不上&#xff1f; 作为转行AI的产品经理&#xff0c;你可能已经体会到了计算机视觉的魅力——但更可能的是&#xff0c;你正被各种Python版本冲突、CUDA报错和缺失依赖搞…

AI手势识别性能优化:降低资源消耗的详细步骤

AI手势识别性能优化&#xff1a;降低资源消耗的详细步骤 1. 引言&#xff1a;AI 手势识别与追踪的技术价值 随着人机交互技术的快速发展&#xff0c;AI手势识别正逐步成为智能设备、虚拟现实、远程控制等场景中的核心感知能力。传统的触摸或语音交互方式在特定环境下存在局限…