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 极高 高并发分布式系统
相关推荐
JYeontu2 分钟前
浏览器书签还能一键下载B站视频封面?
前端·javascript
陈随易2 分钟前
Bun v1.2.16发布,内存优化,兼容提升,体验增强
前端·后端·程序员
聪明的水跃鱼3 分钟前
Nextjs15 基础配置使用
前端·next.js
happyCoder4 分钟前
如何判断用户设备-window.screen.width方式
前端
wearegogog1234 分钟前
Docker Buildx 简介与安装指南
运维·docker·容器
Sun_light10 分钟前
深入理解JavaScript中的「this」:从概念到实战
前端·javascript
西北大程序猿11 分钟前
服务器代码知识点补充
服务器·开发语言·网络·c++·网络协议
小桥风满袖12 分钟前
Three.js-硬要自学系列33之专项学习基础材质
前端·css·three.js
聪明的水跃鱼16 分钟前
Nextjs15 构建API端点
前端·next.js
小明爱吃瓜33 分钟前
AI IDE(Copilot/Cursor/Trae)图生代码能力测评
前端·ai编程·trae