文章目录
- 配置管理
- 引入jar包
- 添加 bootstrap.yaml 文件配置
- 在application.yaml 中添加自定义信息
- nacos 配置信息
- 配置热更新
- 采用第一种配置
- 根据服务名确定配置文件
- 根据后缀确定配置文件
- 动态路由
- DynamicRouteLoader
- NacosConfigManager
- RouteDefinitionWriter
- 路由配置
配置管理
统一配置管理可以解决多服务配置过的问题,同时该服务配置文件移交配置中心 处理信息
引入jar包
配置 pom.xml 添加 config 和 bootstrap 的 jar 包
<!--nacos配置管理-->
<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.yaml 文件配置
配置说明
spring.application.name: 指定微服务的名称(cart-service),Nacos 会根据该名称加载对应的配置。
spring.profiles.active: 指定当前激活的环境(dev),Nacos 会加载 cart-service-dev.yaml 配置。
spring.cloud.nacos.server-addr: 指定 Nacos 服务器的地址(127.0.0.1:8848)。
spring.cloud.nacos.config.file-extension: 指定配置文件的格式为 yaml。
spring.cloud.nacos.config.shared-configs: 定义共享配置,多个微服务可以共用这些配置。
spring:application:name: cart-service # 服务名称profiles:active: devcloud:nacos:server-addr: 127.0.0.1:8848# nacos地址config:file-extension: yaml # 文件后缀名shared-configs: # 共享配置- dataId: shared-jdbc.yaml # 共享mybatis配置- dataId: shared-log.yaml # 共享日志配置- dataId: shared-swagger.yaml # 共享日志配置
在application.yaml 中添加自定义信息
hm:db:batabase: hm-carthost: 127.0.0.1port: 3306username: rootpassword: password
nacos 配置信息
shared-log.yaml
logging:level:com.hmall: debugpattern:dateformat: HH:mm:ss:SSSfile:path: "logs/${spring.application.name}"
shared-jdbc.yaml
spring:datasource:url: jdbc:mysql://${hm.db.host:127.0.0.1}:${hm.db.port:3306}/${hm.db.batabase}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: ${hm.db.username}password: ${hm.db.password}
mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandlerglobal-config:db-config:update-strategy: not_nullid-type: auto
shared-swagger.yaml
knife4j:enable: trueopenapi:title: ${hm.swagger.title:接口文档}description: ${hm.swagger.desc:接口文档信息}email: testconcat: testurl: testversion: v1.0.0group:default:group-name: defaultapi-rule: packageapi-rule-resources:- ${hm.swagger.package}
配置热更新
当修改配置文件时,微服务无需重启即可生效
项目启动时 会去加载 相关配置 文件
Nacos 支持配置的动态更新。当配置文件在 Nacos 中修改后,应用会实时获取最新配置,无需重启。
采用第一种配置
@Data
@Component
@ConfigurationProperties(prefix = "hm.cart")
public class CartProperties {private Integer maxItems;}
nacos 配置 相关信息
根据服务名确定配置文件
在 Spring Cloud 应用中,Nacos 可以根据 spring.application.name 指定的服务名来加载对应的配置文件。例如:
服务名:user-service
Nacos 中的配置文件:user-service.properties 或 user-service.yaml
应用启动时,Nacos 会自动加载与服务名匹配的配置文件。
根据后缀确定配置文件
Nacos 还支持通过后缀来区分不同的配置文件。例如:
服务名:user-service
环境:dev
Nacos 中的配置文件:user-service-dev.properties 或 user-service-dev.yaml
在 Spring Cloud 中,可以通过 spring.profiles.active 指定环境后缀,Nacos 会加载对应环境的配置文件。
动态路由
要实现动态路由首先要将路由配置保存到Nacos,当Nacos中的路由配置变更时,推送最新配置到网关,实时更新网关中的路由信息。
我们需要完成两件事情:
- 监听Nacos配置变更的消息
- 当配置变更时,将最新的路由信息更新到网关路由表
DynamicRouteLoader
DynamicRouteLoader
是一个 Spring Cloud Gateway 的组件,用于从 Nacos 动态加载和更新路由配置。它通过监听 Nacos 配置中心的变化,实时更新网关的路由信息。
- DynamicRouteLoader 类:
- 负责从 Nacos 动态加载路由配置,并在配置发生变化时更新网关的路由表。
- 使用 NacosConfigManager 从 Nacos 获取配置数据,并监听配置变化。
- 依赖注入:
- NacosConfigManager:用于与 Nacos 配置中心交互,获取配置数据。
- RouteDefinitionWriter:用于更新 Spring Cloud Gateway 的路由定义。
- routeIds:用于存储当前已加载的路由 ID,方便后续更新时删除旧路由。
- 初始化方法 initRouteConfig:
- 在项目启动时调用(通过 @PostConstruct 注解)。
- 从 Nacos 获取初始的路由配置(dataId 为 gateway-routes.json,group 为 DEFAULT_GROUP)。
- 添加一个监听器,当 Nacos 中的配置发生变化时,自动调用 updateConfigInfo 方法更新路由。
- 配置更新方法 updateConfigInfo:
- 解析从 Nacos 获取的配置信息(JSON 格式),并将其转换为 RouteDefinition 对象列表。
- 删除旧的路由配置(通过 routeIds 中存储的路由 ID)。
- 清空 routeIds,然后遍历新的路由配置,将其保存到 RouteDefinitionWriter 中,并更新 routeIds。
package com.hmall.gateway.routers;import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;@Slf4j
@Component
@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<>();@PostConstructpublic void initRouteConfig() throws NacosException {// 项目启动时, 拉取配置信息, 并添加监听器String configInfo = nacosConfigManager.getConfigService().getConfigAndSignListener(dataId, group, 5000, new Listener() {@Overridepublic Executor getExecutor() {return null;}@Overridepublic void receiveConfigInfo(String configInfo) {updateConfigInfo(configInfo);}});// 读取到配置,更新路由表updateConfigInfo(configInfo);}public void updateConfigInfo(String configInfo){log.debug("监听获取路由配置信息:{}", configInfo );// 解析配置信息, 转为RouteDefinitionList<RouteDefinition> routeDefinitions = JSONUtil.toList(configInfo, RouteDefinition.class);// 删除旧的路由表信息routeIds.forEach(e->{writer.delete(Mono.just(e)).subscribe();});// 清空id 表routeIds.clear();// 遍历路由信息for (RouteDefinition routeDefinition: routeDefinitions) {// 更新路由表writer.save(Mono.just(routeDefinition)).subscribe();routeIds.add(routeDefinition.getId());}}
}
NacosConfigManager
NacosConfigManager 是 Spring Cloud Alibaba Nacos 提供的一个核心类,用于管理与 Nacos 配置中心的交互。它封装了 Nacos 配置客户端的操作,简化了从 Nacos 获取配置、监听配置变化等功能的实现。
NacosConfigManager 的作用
- 配置管理:
- 提供从 Nacos 配置中心获取配置的能力。
- 支持动态监听配置变化,实时更新本地配置。
- 简化操作:
- 封装了 Nacos 客户端的底层操作,开发者无需直接操作 Nacos 的原生 API。
- 与 Spring Cloud 集成:
- 作为 Spring Cloud Alibaba 的一部分,与 Spring Cloud 的配置管理机制无缝集成。
NacosConfigManager 的核心方法
获取配置
String getConfig(String dataId, String group, long timeoutMs) throws NacosException;
- 作用:从 Nacos 配置中心获取指定 dataId 和 group 的配置内容。
- 参数:
- dataId:配置的唯一标识符(如 gateway-routes.json)。
- group:配置的分组(如 DEFAULT_GROUP)。
- timeoutMs:获取配置的超时时间(毫秒)。
- 返回值:配置内容的字符串形式。
添加监听器
void addListener(String dataId, String group, Listener listener) throws NacosException;
- 作用:为指定 dataId 和 group 的配置添加监听器,当配置发生变化时触发回调。
- 参数:
- dataId:配置的唯一标识符。
- group:配置的分组。
- listener:监听器接口,实现 receiveConfigInfo 方法以处理配置变化。
获取 ConfigService
ConfigService getConfigService();
- 作用:获取底层的 ConfigService 对象,用于直接操作 Nacos 配置客户端。
- 返回值:ConfigService 实例。
RouteDefinitionWriter
RouteDefinitionWriter 是 Spring Cloud Gateway 提供的一个核心接口,用于动态管理路由定义(RouteDefinition)。它允许在运行时添加、删除或更新路由,从而实现动态路由的功能。
RouteDefinitionWriter 的作用
- 动态路由管理:
- 提供添加、删除和更新路由的能力。
- 支持在运行时修改路由配置,无需重启网关服务。
- 与 Spring Cloud Gateway 集成:
- 作为 Spring Cloud Gateway 的一部分,与网关的路由机制无缝集成。
- 响应式编程支持:
- 基于 Reactor 的响应式编程模型,所有操作返回
Mono<Void>
。
RouteDefinitionWriter 的核心方法
保存路由
Mono<Void> save(Mono<outeDefinition> route);
- 作用:保存一个路由定义。
- 参数:
- route:RouteDefinition 对象,表示一个路由规则。
- 返回值:
Mono<Void>
,表示操作完成后的信号。
删除路由
Mono<Void> delete(Mono<String> routeId);
- 作用:根据路由 ID 删除一个路由定义。
- 参数:
- routeId:路由的唯一标识符。
- 返回值:
Mono<Void>
,表示操作完成后的信号。
路由配置
在 nacos 中添加 gateway-routes.json 配置文件 信息 实现动态路由
id
: 路由的唯一标识符,值为 item。
uri
: 路由的目标服务地址,lb://item-service 表示通过负载均衡访问 item-service。
predicates
: 路由的匹配条件。
name
: 使用 Path 断言,表示根据请求路径匹配。
args
: 路径匹配规则。
_genkey_0
: /items/,匹配以 /items/ 开头的请求。
_genkey_1
: /search/,匹配以 /search/ 开头的请求。
filters
: 路由过滤器列表,当前为空。
[{"id": "item","uri": "lb://item-service","predicates": [{"name": "Path","args": {"_genkey_0": "/items/**","_genkey_1": "/search/**"}}],"filters": []},{"id": "user","uri": "lb://user-service","predicates": [{"name": "Path","args": {"_genkey_0": "/users/**","_genkey_1": "/addresses/**"}}],"filters": []},{"id": "cart","uri": "lb://cart-service","predicates": [{"name": "Path","args": {"_genkey_0": "/carts/**"}}],"filters": []}
]