目前Spring Cloud的路由网关方案主要是:Spring Cloud Gateway。默认便有自动更新路由的实现。通过 RouteRefreshListener
检测到更新条件发送 RefreshRoutesEvent
事件实现。更新条件:在服务启动时、新服务注册时、配置中心配置修改时、心跳更新时都会触发。
下面说下自己实现的方案,可以根据自身情况,自定义路由定义实体类。
使用Nacos配置监听方式
思路:监听配置变化,然后 RouteDefinitionWriter
更新路由规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| @Configuration public class DynamicRouteConfig { @Autowired private RouteDefinitionWriter routeDefinitionWriter; @Autowired private ConfigService configService; @PostConstruct public void initRoute() throws NacosException { configService.addListener("gateway-routes.json", "DEFAULT_GROUP", new Listener() { @Override public void receiveConfigInfo(String configInfo) { try { clearExistingRoutes(); List<RouteDefinition> routeDefinitions = JSON.parseArray(configInfo, RouteDefinition.class); routeDefinitions.forEach(routeDefinition -> { try { routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe(); } catch (Exception e) { log.error("更新路由失败", e); } }); } catch (Exception e) { log.error("路由更新失败", e); } } @Override public Executor getExecutor() { return null; } }); } private void clearExistingRoutes() { RouteDefinitionLocator routeDefinitionLocator = SpringUtil.getBean(RouteDefinitionLocator.class); routeDefinitionLocator.getRouteDefinitions() .subscribe(routeDefinition -> { try { routeDefinitionWriter.delete(Mono.just(routeDefinition.getId())).subscribe(); } catch (Exception e) { log.error("删除路由失败", e); } }); } }
|
使用Spring Cloud Bus实现自动刷新
思路:依赖配置服务后,我们可以 @RefreshScope
决定一个类自动刷新配置,包括类的创建,定义自己的RouteLocator, 每当配置更新时,根据配置重新创建 RouteLocator,更新路由规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @RefreshScope @Configuration public class GatewayConfig { @Value("${spring.cloud.gateway.routes}") private String routesConfig; @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .build(); } }
|