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 极高 高并发分布式系统
相关推荐
翻滚吧键盘9 分钟前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
眠修13 分钟前
Kuberrnetes 服务发布
linux·运维·服务器
秃了也弱了。28 分钟前
Chrome谷歌浏览器插件ModHeader,修改请求头,开发神器
前端·chrome
乆夨(jiuze)1 小时前
记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。
前端·javascript·vue.js
好奇的菜鸟1 小时前
Docker 配置项详解与示例
运维·docker·容器
忧郁的蛋~1 小时前
HTML表格导出为Excel文件的实现方案
前端·html·excel
小彭努力中1 小时前
141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
前端·javascript·vue.js·交互
xcs194051 小时前
集运维 麒麟桌面版v10 sp1 2403 aarch64 离线java开发环境自动化安装
运维·自动化
然我1 小时前
别再只用 base64!HTML5 的 Blob 才是二进制处理的王者,面试常考
前端·面试·html
NanLing2 小时前
【纯前端推理】纯端侧 AI 对象检测:用浏览器就能跑的深度学习模型
前端