找回密码
 立即注册
首页 业界区 业界 Spring Cloud Gateway WebFlux 模式架构分析

Spring Cloud Gateway WebFlux 模式架构分析

国瑾瑶 前天 00:00
Spring Cloud Gateway WebFlux 模式架构分析

请关注微信公众号:阿呆-bot
1. 入口类及关键类关系

1.1 入口类

Spring Cloud Gateway WebFlux 模式的入口类是 GatewayAutoConfiguration,这是整个 WebFlux 模式的"总指挥"。它负责配置所有 Gateway 需要的组件。
  1. @Configuration(proxyBeanMethods = false)
  2. @ConditionalOnProperty(name = "spring.cloud.gateway.server.webflux.enabled", matchIfMissing = true)
  3. @EnableConfigurationProperties
  4. @AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class })
  5. @AutoConfigureAfter({ GatewayReactiveLoadBalancerClientAutoConfiguration.class,
  6.         GatewayClassPathWarningAutoConfiguration.class })
  7. @ConditionalOnClass(DispatcherHandler.class)
  8. public class GatewayAutoConfiguration {
  9.     // 核心 Bean 定义
  10. }
复制代码
关键特性说明

  • @AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class })

    • 这个很关键!Gateway 必须在 WebFlux 的默认配置之前加载
    • 为什么?因为 Gateway 需要注册自己的 HandlerMapping(RoutePredicateHandlerMapping)
    • 如果 WebFlux 的默认配置先加载,可能会注册其他的 HandlerMapping,导致路由冲突
    • Gateway 的 HandlerMapping 优先级更高,会优先处理请求

  • @ConditionalOnClass(DispatcherHandler.class)

    • 这个注解确保只有在 WebFlux 存在时才加载 Gateway
    • DispatcherHandler 是 WebFlux 的核心组件,类似于 WebMVC 的 DispatcherServlet
    • 如果没有 WebFlux,Gateway WebFlux 模式就无法工作

  • @ConditionalOnProperty
    1. # 可以通过配置控制是否启用
    2. spring:
    3.   cloud:
    4.     gateway:
    5.       server:
    6.         webflux:
    7.           enabled: true  # 默认启用,可以设置为 false 禁用
    复制代码
配置的核心组件

  • RouteLocator:路由定位器,负责提供路由列表
  • FilteringWebHandler:过滤器处理器,负责执行过滤器链
  • RoutePredicateHandlerMapping:路由匹配器,负责匹配请求到路由
  • GatewayProperties:Gateway 配置属性
1.2 关键类关系图

1.png

1.3 核心组件说明

RoutePredicateHandlerMapping

这是 Gateway 的路由匹配器,负责找到匹配的路由。它继承自 Spring WebFlux 的 AbstractHandlerMapping。
工作原理
  1. @Override
  2. protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
  3.     // 1. 查找匹配的路由(异步操作)
  4.     return lookupRoute(exchange)
  5.         .map(route -> {
  6.             // 2. 把路由信息存储到 Exchange 的属性中
  7.             exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, route);
  8.             // 3. 返回 FilteringWebHandler 作为处理器
  9.             return webHandler;
  10.         });
  11. }
复制代码
实际例子
  1. // 假设有这些路由配置
  2. routes = [
  3.     { id: "user-service", path: "/api/users/**", uri: "http://user-service" },
  4.     { id: "order-service", path: "/api/orders/**", uri: "http://order-service" }
  5. ]
  6. // 请求:GET /api/users/123
  7. // lookupRoute() 会:
  8. // 1. 遍历所有路由
  9. // 2. 使用 AsyncPredicate 异步匹配
  10. // 3. 找到匹配的路由:user-service
  11. // 4. 返回 FilteringWebHandler
复制代码
关键点

  • lookupRoute() 返回 Mono,是异步的
  • 路由匹配使用 AsyncPredicate,支持异步条件判断
  • 匹配成功后,路由信息存储在 ServerWebExchange 的属性中
FilteringWebHandler

这是 Gateway 的核心请求处理器,负责执行过滤器链。它实现了 Spring WebFlux 的 WebHandler 接口。
工作原理
  1. @Override
  2. public Mono<Void> handle(ServerWebExchange exchange) {
  3.     // 1. 从 Exchange 中获取路由信息(路由匹配时设置的)
  4.     Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
  5.    
  6.     // 2. 获取合并后的过滤器列表(全局过滤器 + 路由过滤器)
  7.     List<GatewayFilter> combined = getCombinedFilters(route);
  8.    
  9.     // 3. 创建过滤器链并执行
  10.     return new DefaultGatewayFilterChain(combined).filter(exchange);
  11. }
复制代码
实际例子
  1. // 假设路由配置了这些过滤器
  2. route.filters = [
  3.     AddRequestHeaderFilter,
  4.     RateLimitFilter,
  5.     NettyRoutingFilter  // 最后一个,负责实际转发请求
  6. ]
  7. // FilteringWebHandler 会:
  8. // 1. 合并全局过滤器和路由过滤器
  9. // 2. 按 Order 排序
  10. // 3. 创建过滤器链
  11. // 4. 依次执行过滤器
复制代码
过滤器链执行
  1. // 过滤器链的实现(责任链模式)
  2. private static class DefaultGatewayFilterChain implements GatewayFilterChain {
  3.     @Override
  4.     public Mono<Void> filter(ServerWebExchange exchange) {
  5.         return Mono.defer(() -> {
  6.             if (this.index < filters.size()) {
  7.                 GatewayFilter filter = filters.get(this.index);
  8.                 // 创建下一个链节点
  9.                 DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
  10.                 // 执行当前过滤器,传入下一个链节点
  11.                 return filter.filter(exchange, chain);
  12.             }
  13.             return Mono.empty();  // 所有过滤器执行完毕
  14.         });
  15.     }
  16. }
复制代码
RouteLocator

路由定位器,负责提供路由列表。Gateway 支持多个 RouteLocator,可以组合使用。
工作原理
  1. @Bean
  2. @Primary
  3. public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
  4.     // 1. 组合多个 RouteLocator
  5.     CompositeRouteLocator composite = new CompositeRouteLocator(
  6.         Flux.fromIterable(routeLocators)
  7.     );
  8.    
  9.     // 2. 添加缓存(提高性能)
  10.     return new CachingRouteLocator(composite);
  11. }
复制代码
实际例子
  1. // 可以有多个 RouteLocator
  2. RouteLocator[] locators = [
  3.     PropertiesRouteDefinitionLocator,      // 从配置文件读取路由
  4.     DiscoveryClientRouteDefinitionLocator, // 从服务发现读取路由
  5.     InMemoryRouteDefinitionRepository      // 从内存(API)读取路由
  6. ]
  7. // CompositeRouteLocator 会合并所有路由
  8. // 返回 Flux<Route>,包含所有路由
复制代码
路由来源

  • 配置文件:PropertiesRouteDefinitionLocator
    1. spring:
    2.   cloud:
    3.     gateway:
    4.       routes:
    5.         - id: user-service
    6.           uri: http://localhost:8081
    复制代码
  • 服务发现:DiscoveryClientRouteDefinitionLocator
    1. // 自动从 Eureka/Consul 等服务注册中心发现服务
    2. // 为每个服务自动创建路由
    复制代码
  • API 动态配置:InMemoryRouteDefinitionRepository
    1. // 通过 API 动态添加/删除路由
    2. routeDefinitionRepository.save(routeDefinition);
    复制代码
2. 关键流程描述

2.1 请求处理流程时序图

2.png

2.2 路由匹配流程

路由匹配是 Gateway 的核心功能。让我们用一个实际例子来说明整个流程:
场景:客户端请求 GET /api/users/123
详细流程

  • DispatcherHandler 接收 HTTP 请求
    1. 客户端 → DispatcherHandler → Gateway
    复制代码

    • DispatcherHandler 是 WebFlux 的请求分发器,类似于 WebMVC 的 DispatcherServlet
    • 它会把请求交给合适的 HandlerMapping 处理
    • Gateway 的 RoutePredicateHandlerMapping 优先级很高,会优先处理

  • RoutePredicateHandlerMapping 从 RouteLocator 获取所有路由
    1. // 获取所有路由(返回 Flux<Route>,是响应式的)
    2. Flux<Route> routes = routeLocator.getRoutes();
    3. // 实际的路由列表可能是:
    4. // [
    5. //   { id: "user-service", path: "/api/users/**", uri: "http://user-service" },
    6. //   { id: "order-service", path: "/api/orders/**", uri: "http://order-service" }
    7. // ]
    复制代码

    • RouteLocator 可能从多个来源获取路由(配置文件、服务发现、API)
    • 返回的是 Flux,是响应式的流

  • 使用 AsyncPredicate 异步匹配路由
    1. // 异步匹配路由
    2. return routes
    3.     .filterWhen(route -> {
    4.         // 使用 AsyncPredicate 异步匹配
    5.         return route.getPredicate().test(exchange);
    6.     })
    7.     .next();  // 返回第一个匹配的路由
    复制代码
    匹配过程
    1. // 路由1:user-service
    2. AsyncPredicate predicate1 = exchange -> {
    3.     String path = exchange.getRequest().getPath().value();
    4.     return Mono.just(path.startsWith("/api/users/"));  // 异步返回 true/false
    5. };
    6. // 路径 "/api/users/123" 匹配 "/api/users/**" ✓
    7. // 路由2:order-service
    8. AsyncPredicate predicate2 = exchange -> {
    9.     String path = exchange.getRequest().getPath().value();
    10.     return Mono.just(path.startsWith("/api/orders/"));  // 异步返回 false
    11. };
    12. // 路径 "/api/users/123" 不匹配 "/api/orders/**" ✗
    复制代码

    • 使用 AsyncPredicate 异步匹配,支持异步条件判断
    • 可以在这里做异步操作(比如查询 Redis、数据库等)
    • 返回 Mono,不会阻塞线程

  • 找到匹配的路由后,将路由信息存储到 ServerWebExchange 的属性中
    1. // 匹配成功后
    2. Route matchedRoute = ...;  // user-service 路由
    3. // 存储路由信息到 Exchange 的属性中
    4. exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, matchedRoute);
    5. exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, matchedRoute.getUri());
    复制代码

    • 路由信息存储在 ServerWebExchange 的属性中
    • 后续的过滤器可以从这里获取路由信息
    • 比如 NettyRoutingFilter 会从这里获取目标 URI

  • 返回 FilteringWebHandler 作为处理器
    1. // 返回 FilteringWebHandler
    2. return Mono.just(webHandler);
    复制代码

    • FilteringWebHandler 会负责执行过滤器链
    • 最终会调用 NettyRoutingFilter 转发请求到下游服务

完整示例
  1. # 配置文件
  2. spring:
  3.   cloud:
  4.     gateway:
  5.       routes:
  6.         - id: user-service
  7.           uri: http://user-service:8081
  8.           predicates:
  9.             - Path=/api/users/**
  10.             - Method=GET
复制代码
匹配过程

  • 请求 GET /api/users/123 到达
  • 路径 /api/users/123 匹配 /api/users/** ✓
  • 方法 GET 匹配 GET ✓
  • 找到匹配的路由 user-service
  • 返回 FilteringWebHandler,目标 URI 是 http://user-service:8081
2.3 过滤器链执行流程

过滤器链是 Gateway 的核心机制。让我们用一个实际例子来说明:
场景:请求已经匹配到路由,现在需要执行过滤器链
详细流程

  • FilteringWebHandler 从路由中获取过滤器列表
    1. Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
    2. List<GatewayFilter> routeFilters = route.getFilters();
    3. // 假设路由配置了这些过滤器:
    4. // [AddRequestHeaderFilter, RateLimitFilter]
    复制代码

    • 从路由中获取路由级别的过滤器
    • 这些过滤器只应用于当前路由

  • 合并全局过滤器和路由过滤器,按 Order 排序
    1. // 全局过滤器(应用于所有路由)
    2. List<GlobalFilter> globalFilters = [
    3.     LoadBalancerClientFilter,      // Order: 10100
    4.     NettyRoutingFilter,            // Order: Ordered.LOWEST_PRECEDENCE
    5.     NettyWriteResponseFilter       // Order: Ordered.LOWEST_PRECEDENCE - 1
    6. ];
    7. // 路由过滤器
    8. List<GatewayFilter> routeFilters = [
    9.     AddRequestHeaderFilter,         // Order: 1000
    10.     RateLimitFilter                 // Order: -100
    11. ];
    12. // 合并并排序
    13. List<GatewayFilter> combined = [
    14.     RateLimitFilter,                // -100 (最高优先级)
    15.     AddRequestHeaderFilter,         // 1000
    16.     LoadBalancerClientFilter,       // 10100
    17.     NettyRoutingFilter,             // LOWEST_PRECEDENCE
    18.     NettyWriteResponseFilter        // LOWEST_PRECEDENCE - 1
    19. ];
    复制代码

    • 全局过滤器 + 路由过滤器 = 合并后的过滤器列表
    • 按 Order 排序,数字越小优先级越高
    • Ordered.LOWEST_PRECEDENCE 是最大整数,优先级最低

  • 创建 DefaultGatewayFilterChain,实现责任链模式
    1. // 创建过滤器链
    2. DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(combined);
    3. // 过滤器链的内部实现
    4. private static class DefaultGatewayFilterChain implements GatewayFilterChain {
    5.     private final int index;  // 当前执行的过滤器索引
    6.     private final List<GatewayFilter> filters;
    7.     @Override
    8.     public Mono<Void> filter(ServerWebExchange exchange) {
    9.         return Mono.defer(() -> {
    10.             if (this.index < filters.size()) {
    11.                 GatewayFilter filter = filters.get(this.index);
    12.                 // 创建下一个链节点
    13.                 DefaultGatewayFilterChain nextChain =
    14.                     new DefaultGatewayFilterChain(this, this.index + 1);
    15.                 // 执行当前过滤器,传入下一个链节点
    16.                 return filter.filter(exchange, nextChain);
    17.             }
    18.             return Mono.empty();  // 所有过滤器执行完毕
    19.         });
    20.     }
    21. }
    复制代码

    • 使用责任链模式,每个过滤器都可以决定是否继续执行下一个过滤器
    • 通过递归创建链节点来实现

  • 递归执行过滤器
    1. // 执行流程(简化版)
    2. RateLimitFilter.filter(exchange, chain1)
    3.   -> 检查限流
    4.   -> chain1.filter(exchange)  // 调用下一个过滤器
    5.     -> AddRequestHeaderFilter.filter(exchange, chain2)
    6.       -> 添加请求头
    7.       -> chain2.filter(exchange)  // 调用下一个过滤器
    8.         -> LoadBalancerClientFilter.filter(exchange, chain3)
    9.           -> 负载均衡选择实例
    10.           -> chain3.filter(exchange)
    11.             -> NettyRoutingFilter.filter(exchange, chain4)
    12.               -> 转发请求到下游服务
    13.               -> chain4.filter(exchange)
    14.                 -> NettyWriteResponseFilter.filter(exchange, chain5)
    15.                   -> 写入响应
    16.                   -> chain5.filter(exchange)
    17.                     -> Mono.empty()  // 所有过滤器执行完毕
    复制代码

    • 每个过滤器调用 chain.filter(exchange) 来执行下一个过滤器
    • 如果某个过滤器不想继续执行,可以不调用 chain.filter()
    • 比如限流过滤器,如果限流了,就直接返回错误,不继续执行

  • NettyRoutingFilter 作为最后一个过滤器,执行实际的 HTTP 请求
    1. // NettyRoutingFilter 的实现(简化版)
    2. @Override
    3. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    4.     URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
    5.     // 使用 Reactor Netty HttpClient 发送请求(非阻塞)
    6.     return httpClient.get()
    7.         .uri(requestUrl)
    8.         .send((req, nettyOutbound) -> nettyOutbound.send(request.getBody()))
    9.         .responseConnection((res, connection) -> {
    10.             // 设置响应到 Exchange
    11.             exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);
    12.             return Mono.just(res);
    13.         })
    14.         .then(chain.filter(exchange));  // 继续执行下一个过滤器
    15. }
    复制代码

    • NettyRoutingFilter 使用 Reactor Netty 的 HttpClient 发送请求
    • 这是非阻塞的,线程不会在这里等待
    • 响应到达后,会继续执行下一个过滤器(NettyWriteResponseFilter)

  • 响应通过 Mono 链式返回
    1. // 响应返回流程
    2. NettyWriteResponseFilter.filter(exchange, chain)
    3.   -> 写入响应到客户端
    4.   -> Mono.empty()  // 完成
    5.   -> 返回给 NettyRoutingFilter
    6.     -> 返回给 LoadBalancerClientFilter
    7.       -> 返回给 AddRequestHeaderFilter
    8.         -> 返回给 RateLimitFilter
    9.           -> 返回给 FilteringWebHandler
    10.             -> 返回给 RoutePredicateHandlerMapping
    11.               -> 返回给 DispatcherHandler
    12.                 -> 返回给客户端
    复制代码

    • 响应通过 Mono 链式返回
    • 每个过滤器都可以修改响应
    • 最终返回给客户端

关键点

  • 过滤器链是响应式的,不会阻塞线程
  • 每个过滤器都可以修改请求或响应
  • 过滤器可以决定是否继续执行下一个过滤器
  • NettyRoutingFilter 是最后一个过滤器,负责实际转发请求
2.4 响应式 HTTP 请求
  1. Flux<HttpClientResponse> responseFlux = httpClient
  2.     .headers(headers -> headers.add(httpHeaders))
  3.     .request(method)
  4.     .uri(url)
  5.     .send((req, nettyOutbound) -> nettyOutbound.send(request.getBody()))
  6.     .responseConnection((res, connection) -> {
  7.         // 处理响应
  8.         return Mono.just(res);
  9.     });
复制代码
关键点

  • 使用 Reactor Netty 的非阻塞 HTTP 客户端
  • 基于 Reactive Streams 的响应式编程模型
  • 支持背压(Backpressure)控制
3. 实现关键点说明

3.1 响应式编程模型

WebFlux 模式完全基于响应式编程,使用 Project Reactor 的 Mono 和 Flux。这是 WebFlux 和 WebMVC 最根本的区别。
基本概念
  1. public interface GlobalFilter {
  2.     Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
  3. }
复制代码
Mono 和 Flux 是什么?

  • Mono:表示 0 或 1 个元素的异步序列
    1. Mono<String> name = Mono.just("Spring");  // 一个值
    2. Mono<String> empty = Mono.empty();        // 0 个值
    3. Mono<String> async = Mono.fromCallable(() -> {
    4.     // 异步操作
    5.     return fetchNameFromDatabase();
    6. });
    复制代码
  • Flux:表示 0 到 N 个元素的异步序列
    1. Flux<String> names = Flux.just("Spring", "Cloud", "Gateway");  // 多个值
    2. Flux<String> stream = Flux.interval(Duration.ofSeconds(1))
    3.     .map(i -> "Event " + i);  // 无限流
    复制代码
实际例子
  1. // WebMVC 方式(阻塞)
  2. public ServerResponse handle(ServerRequest request) {
  3.     User user = userService.getUser(userId);  // 阻塞等待
  4.     return ServerResponse.ok().body(user);
  5. }
  6. // WebFlux 方式(非阻塞)
  7. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  8.     return userService.getUser(userId)  // 返回 Mono<User>,不阻塞
  9.         .flatMap(user -> {
  10.             // 用户数据到达后才执行这里
  11.             exchange.getAttributes().put("user", user);
  12.             return chain.filter(exchange);
  13.         });
  14. }
复制代码
优势说明

  • 非阻塞 I/O,提高并发性能
    1. // 非阻塞调用下游服务
    2. return httpClient.get()
    3.     .uri("http://backend-service/api/data")
    4.     .retrieve()
    5.     .bodyToMono(String.class)  // 返回 Mono,不阻塞线程
    6.     .flatMap(data -> {
    7.         // 数据到达后才执行这里
    8.         return processData(data);
    9.     });
    10. // 在等待响应的这段时间,线程可以处理其他请求
    复制代码

    • 线程不会阻塞,可以处理其他请求
    • 一个线程可以处理多个请求
    • 并发性能大幅提升

  • 支持背压,防止内存溢出
    1. // 背压示例
    2. Flux<String> dataStream = getDataStream();  // 数据流
    3. dataStream
    4.     .limitRate(100)  // 限制速率,防止内存溢出
    5.     .subscribe(data -> {
    6.         // 处理数据
    7.         processData(data);
    8.     });
    复制代码

    • 如果生产者生产数据太快,消费者可以告诉生产者慢一点
    • 防止内存溢出
    • 这是 Reactive Streams 规范的核心特性

  • 资源利用率高,少量线程处理大量请求
    1. 场景:处理 10000 并发请求
    2. WebMVC: 需要 500 线程,内存 ~500MB
    3. WebFlux: 只需要 16 线程,内存 ~100MB
    4. 资源利用率提升 5 倍!
    复制代码
3.2 过滤器链模式

Gateway 使用责任链模式实现过滤器链。这是 Gateway 的核心设计模式之一。
责任链模式
  1. private static class DefaultGatewayFilterChain implements GatewayFilterChain {
  2.     private final int index;  // 当前过滤器索引
  3.     private final List<GatewayFilter> filters;
  4.    
  5.     @Override
  6.     public Mono<Void> filter(ServerWebExchange exchange) {
  7.         return Mono.defer(() -> {
  8.             if (this.index < filters.size()) {
  9.                 GatewayFilter filter = filters.get(this.index);
  10.                 // 创建下一个链节点
  11.                 DefaultGatewayFilterChain chain =
  12.                     new DefaultGatewayFilterChain(this, this.index + 1);
  13.                 // 执行当前过滤器,传入下一个链节点
  14.                 return filter.filter(exchange, chain);
  15.             }
  16.             return Mono.empty();  // 所有过滤器执行完毕
  17.         });
  18.     }
  19. }
复制代码
实际例子
  1. // 假设有这些过滤器
  2. List<GatewayFilter> filters = [
  3.     RateLimitFilter,        // index 0
  4.     AddRequestHeaderFilter,  // index 1
  5.     NettyRoutingFilter      // index 2
  6. ];
  7. // 执行流程
  8. chain0.filter(exchange)  // index = 0
  9.   -> RateLimitFilter.filter(exchange, chain1)  // index = 1
  10.     -> 检查限流
  11.     -> chain1.filter(exchange)
  12.       -> AddRequestHeaderFilter.filter(exchange, chain2)  // index = 2
  13.         -> 添加请求头
  14.         -> chain2.filter(exchange)
  15.           -> NettyRoutingFilter.filter(exchange, chain3)  // index = 3
  16.             -> 转发请求
  17.             -> chain3.filter(exchange)
  18.               -> index (3) >= filters.size(),返回 Mono.empty()
复制代码
过滤器类型

  • GlobalFilter - 全局过滤器
    1. @Component
    2. public class CustomGlobalFilter implements GlobalFilter, Ordered {
    3.     @Override
    4.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    5.         // 这个过滤器会应用于所有路由
    6.         return chain.filter(exchange);
    7.     }
    8.     @Override
    9.     public int getOrder() {
    10.         return -1;  // 高优先级
    11.     }
    12. }
    复制代码

    • 应用于所有路由
    • 比如认证、日志、监控等

  • GatewayFilter - 路由过滤器
    1. // 通过配置定义的路由过滤器
    2. spring:
    3.   cloud:
    4.     gateway:
    5.       routes:
    6.         - id: user-service
    7.           filters:
    8.             - AddRequestHeader=X-User-Id, 123  # 路由过滤器
    复制代码

    • 只应用于特定路由
    • 通过配置文件或 API 定义

  • Ordered - 控制执行顺序
    1. // 通过 Order 接口控制执行顺序
    2. public class RateLimitFilter implements GlobalFilter, Ordered {
    3.     @Override
    4.     public int getOrder() {
    5.         return -100;  // 数字越小,优先级越高
    6.     }
    7. }
    8. public class LoggingFilter implements GlobalFilter, Ordered {
    9.     @Override
    10.     public int getOrder() {
    11.         return 1000;  // 优先级较低
    12.     }
    13. }
    14. // 执行顺序:RateLimitFilter (-100) -> LoggingFilter (1000)
    复制代码
过滤器可以做什么?

  • 修改请求
    1. @Override
    2. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    3.     ServerHttpRequest request = exchange.getRequest();
    4.     ServerHttpRequest modifiedRequest = request.mutate()
    5.         .header("X-Request-Id", UUID.randomUUID().toString())
    6.         .build();
    7.     return chain.filter(exchange.mutate().request(modifiedRequest).build());
    8. }
    复制代码
  • 修改响应
    1. @Override
    2. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    3.     return chain.filter(exchange).then(Mono.fromRunnable(() -> {
    4.         ServerHttpResponse response = exchange.getResponse();
    5.         response.getHeaders().add("X-Response-Time",
    6.             String.valueOf(System.currentTimeMillis()));
    7.     }));
    8. }
    复制代码
  • 中断执行
    1. @Override
    2. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    3.     if (isRateLimited(exchange)) {
    4.         // 限流了,直接返回错误,不继续执行
    5.         exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
    6.         return exchange.getResponse().setComplete();
    7.     }
    8.     return chain.filter(exchange);  // 继续执行
    9. }
    复制代码
3.3 异步谓词(AsyncPredicate)

路由匹配使用异步谓词,支持异步条件判断:
  1. public interface AsyncPredicate<T> {
  2.     Mono<Boolean> test(T t);
  3. }
复制代码
支持的谓词

  • Path Route Predicate
  • Method Route Predicate
  • Header Route Predicate
  • Host Route Predicate
  • Query Route Predicate
  • RemoteAddr Route Predicate
  • Weight Route Predicate
3.4 Netty 集成

使用 Reactor Netty 作为底层 HTTP 客户端,提供高性能的非阻塞 I/O:
  1. public class NettyRoutingFilter implements GlobalFilter {
  2.     private final HttpClient httpClient;
  3.    
  4.     @Override
  5.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  6.         // 使用 Reactor Netty HttpClient 发送请求
  7.         Flux<HttpClientResponse> responseFlux = httpClient
  8.             .request(method)
  9.             .uri(url)
  10.             .send(...)
  11.             .responseConnection(...);
  12.     }
  13. }
复制代码
特性

  • 基于 Netty 的事件驱动模型
  • 支持 HTTP/1.1 和 HTTP/2
  • 支持 WebSocket
  • 连接池管理
3.5 路由缓存

支持路由过滤器缓存,提高性能:
  1. private final ConcurrentHashMap<Route, List<GatewayFilter>> routeFilterMap = new ConcurrentHashMap();
  2. protected List<GatewayFilter> getCombinedFilters(Route route) {
  3.     if (this.routeFilterCacheEnabled) {
  4.         return routeFilterMap.computeIfAbsent(route, this::getAllFilters);
  5.     }
  6.     return getAllFilters(route);
  7. }
复制代码
4. 总结说明

4.1 架构特点


  • 响应式编程: 完全基于 Project Reactor 的响应式编程模型
  • 非阻塞 I/O: 使用 Reactor Netty 实现非阻塞 HTTP 通信
  • 高并发性能: 少量线程处理大量并发请求
  • 背压支持: 支持 Reactive Streams 的背压机制
4.2 适用场景


  • 高并发、高吞吐量的 API 网关场景
  • 需要处理大量长连接(如 WebSocket)
  • 微服务架构中的统一入口
  • 需要流式处理(Streaming)的场景
4.3 关键优势


  • 高性能: 非阻塞 I/O 提供更高的吞吐量
  • 资源高效: 少量线程处理大量请求,资源利用率高
  • 可扩展性: 响应式模型支持更好的水平扩展
  • 功能丰富: 支持 HTTP/2、WebSocket、gRPC 等协议
4.4 局限性


  • 学习曲线: 需要理解响应式编程模型
  • 调试困难: 异步调用栈较难调试
  • 阻塞风险: 如果在响应式链中执行阻塞操作,会降低性能
  • 内存管理: 需要理解背压机制,避免内存问题
4.5 最佳实践


  • 避免阻塞操作: 不要在响应式链中执行阻塞 I/O
  • 合理使用背压: 理解背压机制,合理配置缓冲区
  • 监控和指标: 使用 Spring Boot Actuator 监控 Gateway 性能
  • 过滤器顺序: 合理设置过滤器顺序,避免不必要的处理

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册