Spring Cloud Gateway MVC结合Eureka服务发现及路由列表获取咨询
解决方案:Spring Cloud Gateway MVC 集成 Eureka 及路由列表获取
1. Gateway MVC 与 Eureka DiscoveryClient 集成配置
依赖配置
先引入 Gateway MVC 和 Eureka Client 核心依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway-mvc</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
应用配置
在 application.yml 中配置 Eureka 连接参数:
spring: application: name: gateway-mvc-service eureka: client: service-url: defaultZone: http://your-eureka-server:8761/eureka/ fetch-registry: true register-with-eureka: true
自动生成Eureka服务路由
创建配置类,基于 DiscoveryClient 为所有注册服务自动生成路由规则:
import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.gateway.mvc.handler.HandlerFunctions; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.function.RequestPredicates; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.ServerResponse; @Configuration public class EurekaRouteConfiguration { @Bean public RouterFunction<ServerResponse> eurekaDiscoveryRoutes(DiscoveryClient discoveryClient) { RouterFunction<ServerResponse> router = RouterFunction.route(); // 遍历Eureka中所有服务,生成路由:/服务ID/** 转发到对应服务 for (String serviceId : discoveryClient.getServices()) { router = router.andRoute( RequestPredicates.path("/" + serviceId + "/**"), HandlerFunctions.http() .uri("lb://" + serviceId + "/{path}") .build() ); } return router; } }
2. 自定义过滤器中获取路由列表
注意:RouteLocator 是 WebFlux 版本 Gateway 的组件,不适用于 MVC 场景。可以通过 RoutePredicateHandlerMapping 获取所有注册的路由信息:
修改过滤器配置类
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.ServerResponse; import org.springframework.web.servlet.handler.RoutePredicateHandlerMapping; @Configuration public class CustomRouteFilterConfiguration { private final RoutePredicateHandlerMapping routeMapping; // 构造注入路由映射器 public CustomRouteFilterConfiguration(RoutePredicateHandlerMapping routeMapping) { this.routeMapping = routeMapping; } @Bean public RouterFunction<ServerResponse> tokenRelay() { return RouterFunction.route("access_control_route") .route(RequestPredicates.path("/**"), HandlerFunctions.http()) .filter(RoutesFilterFunctions.filterOnRoutes(jHipsterProperties, routeMapping)) .build(); } }
修改过滤器实现类
import org.springframework.cloud.gateway.mvc.annotation.Shortcut; import org.springframework.web.servlet.function.HandlerFilterFunction; import org.springframework.web.servlet.function.ServerRequest; import org.springframework.web.servlet.function.ServerResponse; import org.springframework.web.servlet.handler.RoutePredicateHandlerMapping; public class RoutesFilterFunctions { @Shortcut public static HandlerFilterFunction<ServerResponse, ServerResponse> filterOnRoutes(JHipsterProperties jHipsterProperties, RoutePredicateHandlerMapping routeMapping) { return (request, next) -> { boolean isAuthorizedRequest = false; // 遍历所有注册的路由规则,predicate为路由匹配条件,handlerMethod为对应处理逻辑 routeMapping.getHandlerMethods().forEach((predicate, handlerMethod) -> { // 自定义路由校验逻辑,例如判断请求路径是否匹配路由规则 // do something here }); return next.handle(request); }; } }
备选方案:自定义路由注册表
如果需要更灵活的路由信息管理,可以手动维护路由注册表:
// 自定义路由注册表组件 @Component public class RouteRegistry { private final List<RouteMeta> routes = new CopyOnWriteArrayList<>(); public void addRoute(RouteMeta route) { routes.add(route); } public List<RouteMeta> getRoutes() { return routes; } } // 在EurekaRouteConfiguration中注册路由时同步存入注册表 router = router.andRoute(..., ...); routeRegistry.addRoute(new RouteMeta(serviceId, "/"+serviceId+"/**")); // 过滤器中直接读取注册表 public static HandlerFilterFunction<ServerResponse, ServerResponse> filterOnRoutes(RouteRegistry routeRegistry) { return (request, next) -> { for(RouteMeta route : routeRegistry.getRoutes()) { // 自定义逻辑 } return next.handle(request); }; }
内容的提问来源于stack exchange,提问作者j-mk
相关产品推荐
相关产品推荐

