Spring Cloud Gateway 动态路由实现方案

动态路由的核心需求:在不重启网关的情况下,实时修改路由规则。以下是 4 种实现方案:

方案 1:基于内存的动态路由(RefreshRoutesEvent)

适用场景:临时修改,重启失效

java 复制代码
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;

// 添加路由
public void addRoute(RouteDefinition definition) {
    routeDefinitionWriter.save(Mono.just(definition)).subscribe();
    publisher.publishEvent(new RefreshRoutesEvent(this)); // 触发刷新
}

// 删除路由
public void deleteRoute(String routeId) {
    routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
    publisher.publishEvent(new RefreshRoutesEvent(this));
}

缺点:路由数据不持久化

方案 2:数据库存储 + 定时轮询

实现步骤

  1. 创建路由表:
sql 复制代码
CREATE TABLE gateway_routes (
  id VARCHAR(50) PRIMARY KEY,
  uri VARCHAR(100),
  predicates JSON,
  filters JSON,
  `order` INT
);
  1. 自定义 RouteDefinitionRepository
java 复制代码
@Component
public class JdbcRouteDefinitionRepository implements RouteDefinitionRepository {
    
    @Autowired
    private RouteDao routeDao; // 自定义DAO

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        return Flux.fromIterable(routeDao.findAll());
    }
}
  1. 配置定时刷新(可选):
java 复制代码
@Scheduled(fixedRate = 30000)
public void refreshRoutes() {
    publisher.publishEvent(new RefreshRoutesEvent(this));
}
方案 3:Nacos 配置中心动态监听

实现步骤

  1. 添加依赖:
XML 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  1. 在Nacos创建配置(Data ID: gateway-routes.json):
XML 复制代码
[{
  "id": "user-service",
  "predicates": [{"name": "Path", "args": {"pattern": "/user/**"}}],
  "uri": "lb://user-service",
  "filters": []
}]

3.配置监听:

java 复制代码
@RefreshScope
@Configuration
public class NacosDynamicRoutes {
    
    @Value("${spring.cloud.gateway.routes}")
    private String routesConfig;

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        // 解析JSON配置构建路由
        return builder.routes().build();
    }
}
方案 4:Redis Pub/Sub 实时通知

实现步骤

  1. 定义Redis消息监听:
java 复制代码
@Component
public class RouteUpdateListener {
    
    @Autowired
    private ApplicationEventPublisher publisher;

    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory factory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.addMessageListener((message, pattern) -> {
            publisher.publishEvent(new RefreshRoutesEvent(this));
        }, new ChannelTopic("gateway-routes-update"));
        return container;
    }
}

2.修改路由时发布消息:

java 复制代码
redisTemplate.convertAndSend("gateway-routes-update", "refresh");

方案对比

方案 实时性 持久化 复杂度 适用场景
内存刷新 开发测试
数据库存储 中小规模生产环境
Nacos配置中心 阿里云体系
Redis Pub/Sub 极高 高并发分布式系统
相关推荐
掘金安东尼5 小时前
让 JavaScript 更容易「善后」的新能力
前端·javascript·面试
掘金安东尼5 小时前
用 HTMX 为 React Data Grid 加速实时更新
前端·javascript·面试
灵感__idea7 小时前
Hello 算法:众里寻她千“百度”
前端·javascript·算法
yinuo7 小时前
轻松接入大语言模型API -04
前端
袋鼠云数栈UED团队8 小时前
基于 Lexical 实现变量输入编辑器
前端·javascript·架构
cipher8 小时前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
UrbanJazzerati8 小时前
非常友好的Vue 3 生命周期详解
前端·面试
AAA阿giao8 小时前
从零构建一个现代登录页:深入解析 Tailwind CSS + Vite + Lucide React 的完整技术栈
前端·css·react.js
兆子龙9 小时前
像 React Hook 一样「自动触发」:用 Git Hook 拦住忘删的测试代码与其它翻车现场
前端·架构
兆子龙10 小时前
用 Auto.js 实现挂机脚本:从找图点击到循环自动化
前端·架构