在微服务架构中,路由配置的动态更新是非常重要的一个环节。通过动态路由,我们可以在不重启服务的情况下,灵活地增加、修改或删除路由配置。今天,我想和大家分享一个在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<>();
@PostConstruct
public void initRouteConfigListener() throws NacosException {
// 1. 项目启动时,先拉取一次配置,并添加配置监听器
String configInfo = nacosConfigManager.getConfigService()
.getConfigAndSignListener(dataId, group, 500, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public 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实现动态路由配置,大大提高了路由管理的灵活性和效率。在实际项目中,可以根据需求对代码进行扩展和优化,比如添加异常处理、优化性能等。