当前位置: 首页 > news >正文

SpringCloud (3) 配置中心

 将一个大项目拆解成多个微服务时,就会导致:
    ①微服务重复配置过多
    ②业务配置经常变动,每次修改都要重启服务
    ③网关配置写死,如果变更需要重启网关

Nacos不仅有"注册中心"的功能,针对以上问题,Nacos还提供了"配置管理"功能

1 添加配置到Nacos

        添加一些共享配置到Nacos中,比如JDBC,MybatisPlus,日志(logback.xml)等

2 拉取配置

2.1 基于NacosConfig拉取配置

        基于NacosConfig拉取共享配置代替本地微服务的配置,把原本基于SpringBoot加载配置文件的方式改为SpringCloud加载配置文件的方式

2.2 引入依赖

        注意alibaba-nacos-config依赖,如果版本太高可能就不适合本篇文章

<!--nacos配置管理,nacosConfig-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2023.0.1.2</version>
</dependency><!--读取bootstrap文件-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId>
<dependency>

2.3 创建bootstrap.yaml文件

        共享配置管理:优先级低,在bootstrap.yaml文件中通过data-id指定生效

spring:application:name: engineering-----devprofiles:active: devcloud:nacos:server-addr: 123.123.123.123:8848config:file-extension: yaml #文件后缀名/配置格式shared-configs: #共享配置- data-id: share-datasource.yaml- data-id: share-administrators-phonenumber.yaml

        专属配置管理:优先级高,根据Nacos中的Data Id自动与"微服务名-环境"进行匹配生效

                例如在Nacos中创建配置的Data Id为engineering-----dev-dev.yaml,那么此配置就会对名为engineering-----dev的微服务的dev环境生效

3 配置热更新

        修改nacos中的配置时,微服务无需重启即可实时获取最新配置

3.1 热更新条件

        ① Nacos中添加一个与"微服务名"命名的专属配置管理(共享配置管理不行)

        ② spring.application.name必须写在bootstrap.yaml中(不能写在application.yaml中)

3.2 微服务接收热更新数据

3.2.1 方式一

        Prop类+@ConfigurationProperties(prefix = "aaa.bbb")注解

@Component
@ConfigurationProperties(prefix = "aaa.bbb")
public class TestProp {private String ccc;public String getCcc() {return ccc;}public void setCcc(String ccc) {this.ccc = ccc;}
}

        在对应的xxxServiceImpl类中用@Autowired注入成员变量,该成员变量就能接收热更新数据

@Autowired
private TestProp testProp;

3.2.2 方式二

        @RefreshScope注解+@Value("${aaa.bbb.ccc}")注解

        在对应的xxxServiceImpl类用@RefreshScope注解,同时用@Value("${aaa.bbb.ccc}")注入成员变量,该成员变量就能接收热更新数据

@Service
@Transactional
@RefreshScope
public class GuardNetServiceImpl extends ServiceImpl<GuardNetDao, GuardNet> implements GuardNetService {@Value("${aaa.bbb.ccc}")private String ccc;

4 动态路由

        网关启动时,会加载配置文件中的路由信息,然后保存在路由表(缓存)中,之后在处理请求的路由转发时,就无须再去读取配置文件,而是直接读取缓存即可

        但这样就会存在一个问题,即使将gateway模块的配置文件的路由信息写在nacos中,而且能实现"配置热更新",也无法做到路由表的实时更新(因为路由表只在网关启动时读取配置文件,后续对配置文件的热更新不会再被重新读取)

4.1 动态路由实现原理

        ① 路由配置保存到nacos,通过"配置热更新"原理,能实时将最新的路由信息更新到网关gateway模块

        ② 在gateway模块中监听nacos的配置变更,将变更的路由信息更新到路由表

4.2 gateway模块引入依赖

<!--nacos配置管理,nacosConfig-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2023.0.1.2</version>
</dependency><!--读取bootstrap文件-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

4.3 新建"动态路由加载器类",做路由配置变更监听

package xyz.aboluo.gateway.routers;import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.Listener;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executor;import com.alibaba.fastjson2.JSON;
import reactor.core.publisher.Mono;@Component
public class DynamicRouteLoader {@Autowiredprivate NacosConfigManager nacosConfigManager;@Autowiredprivate RouteDefinitionWriter routeDefinitionWriter;@Autowiredprivate ApplicationEventPublisher applicationEventPublisher;private final String dataId = "gateway-route-dev.json";private final String group = "DEFAULT_GROUP";private Set<String> routeIds = new HashSet<>();@PostConstruct  // 在类被初始化进SpringIOC容器时,就调用此方法public void initRouteConfigListener() throws Exception {// 拉取NacosConfig配置并添加监听器String configInfo = nacosConfigManager.getConfigService().getConfigAndSignListener(dataId, group, 5000, new Listener() {@Overridepublic Executor getExecutor() {return null;}@Overridepublic void receiveConfigInfo(String s) {// 监听到配置变更,更新到路由表updateConfigInfo(s);}});// 首次启动时,将拉取的配置信息更新到配置表updateConfigInfo(configInfo);}public void updateConfigInfo(String configInfo) {// 删除旧的路由表for (String routeId : routeIds) {routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();}routeIds.clear();// 更新路由表for (RouteDefinition routeDefinition : JSON.parseArray(configInfo, RouteDefinition.class)) {// 更新路由表routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();// 记录路由id,便于下次更新时删除旧的路由表routeIds.add(routeDefinition.getId());}// 发布路由applicationEventPublisher.publishEvent(new RefreshRoutesEvent(routeDefinitionWriter));}
}

4.4 在nacos配置管理中新建路由规则的json格式配置

        路由规则的json格式与yaml格式对照关系:

http://www.xdnf.cn/news/597151.html

相关文章:

  • vue项目的dist在nginx部署后报错Uncaught SyntaxError
  • 技术篇-2.2.JAVA应用场景及开发工具安装
  • Spring Boot 注解 @ConditionalOnMissingBean是什么
  • 嵌入式开发学习日志(linux系统编程--io文件偏移函数(3)和目录)Day26
  • 文件IO操作、目录操作
  • 【leetcode】3355. 零数组变换Ⅰ
  • HCIP-AI培养计划,成为新时代AI解决方案架构高级工程师
  • Metal入门,使用Metal实现纹理效果
  • SpringBoot的启动原理?
  • 若依代码生成
  • 人工智能时代:从“知识容器”到“知识地图”的认知革命
  • 芯片数据手册下载网站整理
  • 价格行为(PriceAction)复盘 - Google - 250521
  • vector
  • Python训练营---Day33
  • Unity Max SDK接入MRec广告,自定义显示位置
  • Linux spi
  • 投票合约1
  • 二叉树结构与遍历
  • 消费类,小家电产品如何做Type-C PD快充快速充电
  • Hugging Face 设置镜像源 | 下载失败 | 下载的速度很慢
  • 轴承与螺母表面缺陷数据集
  • 全栈开发中主流 AI 编程辅助工具的实践与对比分析20250522
  • 人工智能时代教育信息化领导力的培养与发展研究
  • 【知识图谱-一-综述】
  • 新一代网校培训平台的技术演进:从教育源码开发到AI赋能教学转型
  • debian12安装freeswitch1.10
  • DL00967-通过伪样本合成进行零样本侧扫声纳图像分类含完整数据集
  • Python基础学习-Day32
  • 计算机图形学Games101笔记--光线追踪。RTX ON!!!(<--删除线)