在微服务架构中,路由配置的动态更新是非常重要的一个环节。通过动态路由,我们可以在不重启服务的情况下,灵活地增加、修改或删除路由配置。今天,我想和大家分享一个在Spring Cloud Gateway中如何使用Nacos实现动态路由配置的例子。
背景介绍
在我们日常开发中,经常会遇到这样一个需求:需要在运行时动态地管理路由配置。传统的方式可能需要重启网关服务,这显然不够优雅和高效。为了解决这个问题,我们可以借助Nacos的配置中心功能,结合Spring Cloud Gateway,实现动态路由的加载和更新。
代码实现
下面是实现动态路由加载的关键代码:
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;/*** @since 2024/7/28*/
@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 initRouteConfigListener() throws NacosException {// 1. 项目启动时,先拉取一次配置,并添加配置监听器String configInfo = nacosConfigManager.getConfigService().getConfigAndSignListener(dataId, group, 500, new Listener() {@Overridepublic Executor getExecutor() {return null;}@Overridepublic void receiveConfigInfo(String s) {// 2. 监听到配置变更时,更新路由表updateConfigInfo(s);}});// 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());}}
}
关键步骤解析
- 初始化配置监听器:在项目启动时,调用
initRouteConfigListener
方法,从Nacos配置中心拉取当前的路由配置,并添加配置变更监听器。 - 更新路由配置:当监听器检测到配置变更时,调用
updateConfigInfo
方法更新路由配置。首先解析新的配置,并删除旧的路由,然后将新的路由信息保存到路由表中。 - 日志记录:在更新路由配置的过程中,使用日志记录每一步操作,方便调试和监控。
总结
通过以上的实现,我们可以在Spring Cloud Gateway中使用Nacos实现动态路由配置,大大提高了路由管理的灵活性和效率。在实际项目中,可以根据需求对代码进行扩展和优化,比如添加异常处理、优化性能等。