news 2026/4/24 22:45:04

SpringCloud —— 配置管理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringCloud —— 配置管理

一、前言

至此,微服务的基本开发我们就学习完了,接下来学习的是为了简便维护成本和保障服务安全的技术了,这里首先要讲的就是配置管理,配置管理是通过Nacos来实现的,对复用率高的配置进行统一管理共享,所以在微服务的配置文件中就只需要写参数和部分特殊配置了,简便了开发,并且方便了后期的维护。同时,Nacos的配置管理具有热部署的功能,也就是无需重启服务即可更改配置,所以对于服务的日常维护是有很大好处的。

二、共享配置

刚刚提到了共享配置,其实就是说一份配置多个微服务共同使用,比如像数据库和日志的配置,配置的结构完全相同,仅仅是少部分参数略有不同,这个时候就可以直接共享配置了。

比如购物车微服务,先前的配置如下:

server: port: 8082 spring: application: name: cart-service profiles: active: dev datasource: url: jdbc:mysql://${hm.db.host}:3306/hm-cart?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: root password: ${hm.db.pw} 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}" 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

可以看到是很冗长的,接下来我们拆分配置,将可以值得共享的配置拿出来,创建为一个共享配置:(在Nacos中操作)

1.数据库

spring: datasource: url: jdbc:mysql://${hm.db.host:192.168.242.130}:${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

2.日志

logging: level: com.hmall: debug pattern: dateformat: HH:mm:ss:SSS file: path: "logs/${spring.application.name}"

3.文档

knife4j: enable: true openapi: title: ${hm.swagger.title:黑马商城接口文档} description: "${hm.swagger.desc:黑马商城接口文档}" 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: - ${hm.swagger.package}

最终在nacos中就会变成这样:

4.微服务配置

接下来我们就只需要在微服务的配置对应的参数即可,注意,下面的配置是在bootstrap.yaml中配置的,其中在对nacos的配置中注明了共享配置的id,以便于作为模板使用,这里我们就需要配置刚刚上面三个共享配置的id了(这个id是在nacos中自定义的)。

server: port: 8082 feign: okhttp: enabled: true # 开启OKHttp功能 hm: db: database: hm-cart swagger: title: "黑马商城购物车服务接口文档" package: com.hmall.cart.controller
spring: application: name: cart-service profiles: active: dev cloud: nacos: server-addr: 192.168.242.130:8848 config: file-extension: yaml shared-configs: ->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 中 Data ID 默认是服务名.yml),所以这里我们要注意按照规范定义共享配置的配置名,这个配置名决定了nacos中的配置应用在哪个微服务中(将配置绑定到对应微服务专属的Spring IoC容器中),比如这里是cart-service,那么其他微服务就不会识别到这个配置了。

@Data @Component @ConfigurationProperties(prefix = "hm.cart") public class CartProperties { private Integer maxItems; }

这个时候,我们就可以直接在nacos中更改配置参数了,可以发现,即使微服务不重启,配置的参数也会更改,这就是热更新。

四、动态路由

路由是通过网关来转发的,所以这里的所有配置,都是网关的,首先先用共享配置配置网关,这里只需要一个日志配置就行了,同时,路由配置我们就不要写死了,这里面都是写死的配置,所以我们全部删除了:

spring: application: name: gateway profiles: active: dev cloud: nacos: server-addr: 192.168.242.130:8848 config: file-extension: yaml shared-configs: ->server: port: 8080 spring: application: name: gateway cloud: nacos: server-addr: 192.168.242.130 hm: jwt: location: classpath:hmall.jks alias: hmall password: hmall123 tokenTTL: 30d auth: excludePaths: - /search/** - /users/login - /items/** - /hi

这个就是动态路由加载器,它的原理是用NacosConfigManager获取nacos中的配置然后更新路由表,注意,这里我们必须使用JSON格式来配置路由,因为之前配置文件中的路由底层其实是交给一个类来封装的,也就是说,每一个微服务的路由都是一个类的对象,而这个封装的类就是RouteDefinition所以我们最后交给监听器的是RouteDefinition对象的集合,其中的每个对象是由nacos中的JSON配置转化过来的。

而监听器监听的是什么呢?其实就是nacos控制台中配置的更改,只要配置一改变,监听器就会执行updateConfigInfo()方法,从而更新路由表。

@Component @Slf4j @RequiredArgsConstructor public class DynamicRouteLoader { private final NacosConfigManager nacosConfigManager; private final RouteDefinitionWriter writer; private final String dataId = "gateway-routes.json"; private final String group = "DEFAULT_GROUP"; private final Set<String> routeIds = new HashSet<>(); @PostConstruct//在Bean初始化后执行 public void initRouteConfigListener() throws NacosException { //1.项目启动时,先拉起一次配置,并且添加配置监听器 String configInfo = nacosConfigManager.getConfigService() .getConfigAndSignListener(dataId, group, 5000, new Listener() { @Override public Executor getExecutor() { return null; } @Override public void receiveConfigInfo(String configInfo) { //2.监听到配置变更,需要去更新路由表 updateConfigInfo(configInfo); } }); //3.第一次读取到配置,也需要更新到路由表 updateConfigInfo(configInfo); } public void updateConfigInfo(String configInfo) { log.debug("监听到路由配置信息:{}",configInfo); //1.解析配置文件,转换为RouteDefinition List<RouteDefinition> routeDefinitions = JSONUtil.toList(configInfo, RouteDefinition.class); //2.删除旧的路由表 for (String routeId : routeIds) { writer.delete(Mono.just(routeId)).subscribe(); } routeIds.clear(); //3.更新路由表 for (RouteDefinition routeDefinition : routeDefinitions) { //3.1更新路由表 writer.save(Mono.just(routeDefinition)).subscribe(); //3.2记录路由id,便于下一次更新时删除 routeIds.add(routeDefinition.getId()); } } }
[ { "id": "item", "predicates": [{ "name": "Path", "args": {"_genkey_0":"/items/**", "_genkey_1":"/search/**"} }], "filters": [], "uri": "lb://item-service" }, { "id": "cart", "predicates": [{ "name": "Path", "args": {"_genkey_0":"/carts/**"} }], "filters": [], "uri": "lb://cart-service" }, { "id": "user", "predicates": [{ "name": "Path", "args": {"_genkey_0":"/users/**", "_genkey_1":"/addresses/**"} }], "filters": [], "uri": "lb://user-service" }, { "id": "trade", "predicates": [{ "name": "Path", "args": {"_genkey_0":"/orders/**"} }], "filters": [], "uri": "lb://trade-service" }, { "id": "pay", "predicates": [{ "name": "Path", "args": {"_genkey_0":"/pay-orders/**"} }], "filters": [], "uri": "lb://pay-service" } ]
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 3:25:32

掌握这3种VSCode注释模式,轻松驾驭Shor、Grover等量子算法文档

第一章&#xff1a;量子算法文档注释的重要性在量子计算领域&#xff0c;算法的复杂性和抽象性远超经典计算模型。由于量子态叠加、纠缠和干涉等特性&#xff0c;代码逻辑难以直观理解&#xff0c;因此清晰、准确的文档注释成为开发与协作过程中不可或缺的一环。良好的注释不仅…

作者头像 李华
网站建设 2026/4/23 14:59:36

FindSomething隐私检测插件:全方位守护你的上网安全

FindSomething隐私检测插件&#xff1a;全方位守护你的上网安全 【免费下载链接】FindSomething 基于chrome、firefox插件的被动式信息泄漏检测工具 项目地址: https://gitcode.com/gh_mirrors/fi/FindSomething 在网络信息时代&#xff0c;你是否曾担心个人敏感信息在浏…

作者头像 李华
网站建设 2026/4/23 12:15:40

10天拉新3000人,高效版退休俱乐部,靠“赛销一体”跑通银发生意

银发生意如何告别“假繁华”作者&#xff5c;AgeClub吕娆炜前言退休俱乐部&#xff0c;正在成为银发赛道最大的流量入口之一。伴随我国老龄化进程加速&#xff0c;活力老人社交文娱需求显著增长&#xff0c;退休或临近退休不再意味着社会角色的退场&#xff0c;而是解锁一种全新…

作者头像 李华
网站建设 2026/4/21 22:01:12

Azure智能检索与推理引擎:构建企业级知识问答系统的新范式

传统检索增强生成&#xff08;RAG&#xff09;系统在处理复杂业务问题时常常力不从心——用户的多文档关联查询、数值计算需求、逻辑推理问题往往得不到准确回答。Azure Search与OpenAI的深度整合&#xff0c;通过代理检索与推理模型双引擎架构&#xff0c;为企业级知识问答系统…

作者头像 李华
网站建设 2026/4/18 13:48:32

终极Git文件属性管理指南:完整.gitattributes模板集合

终极Git文件属性管理指南&#xff1a;完整.gitattributes模板集合 【免费下载链接】gitattributes 项目地址: https://gitcode.com/gh_mirrors/gita/gitattributes &#x1f3af; 为什么你需要关注这个主题&#xff1f; 在现代软件开发中&#xff0c;Git已成为版本控制…

作者头像 李华
网站建设 2026/4/18 3:43:28

3个常见Quill字号问题及完美解决方案

3个常见Quill字号问题及完美解决方案 【免费下载链接】quill Quill is a modern WYSIWYG editor built for compatibility and extensibility 项目地址: https://gitcode.com/gh_mirrors/qui/quill 你是否在使用Quill编辑器时遇到过这样的困扰&#xff1a;明明设置了字号…

作者头像 李华