Spring Cloud Gateway 动态路由实现方案

发布于:2025-06-13 ⋅ 阅读:(20) ⋅ 点赞:(0)

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

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

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

@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. 创建路由表:

CREATE TABLE gateway_routes (
  id VARCHAR(50) PRIMARY KEY,
  uri VARCHAR(100),
  predicates JSON,
  filters JSON,
  `order` INT
);

  2. 自定义 RouteDefinitionRepository

@Component
public class JdbcRouteDefinitionRepository implements RouteDefinitionRepository {
    
    @Autowired
    private RouteDao routeDao; // 自定义DAO

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        return Flux.fromIterable(routeDao.findAll());
    }
}

 3. 配置定时刷新(可选):

@Scheduled(fixedRate = 30000)
public void refreshRoutes() {
    publisher.publishEvent(new RefreshRoutesEvent(this));
}
方案 3:Nacos 配置中心动态监听

实现步骤

  1. 添加依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

  2. 在Nacos创建配置(Data ID: gateway-routes.json):

[{
  "id": "user-service",
  "predicates": [{"name": "Path", "args": {"pattern": "/user/**"}}],
  "uri": "lb://user-service",
  "filters": []
}]

  3.配置监听:

@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消息监听:

@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.修改路由时发布消息: 

redisTemplate.convertAndSend("gateway-routes-update", "refresh");

方案对比

方案 实时性 持久化 复杂度 适用场景
内存刷新 开发测试
数据库存储 中小规模生产环境
Nacos配置中心 阿里云体系
Redis Pub/Sub 极高 高并发分布式系统