> 技术文档 > Spring Cloud Gateway_Spring Cloud Gateway routing configuration example

Spring Cloud Gateway_Spring Cloud Gateway routing configuration example

# Spring Cloud Gateway资料

所谓的API网关,指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑 可以在这里实现,诸如认证、鉴权、监控、路由转发等等。

  • 全局性流控

  • 日志统计

  • 防止SQL注入

  • 防止Web攻击

  • 屏蔽工具扫描

  • 黑白名单

  • 证书/加解密处理

  • 服务级别流控

  • 服务降级与熔断

  • 路由与负载均衡、灰度策略

  • 服务过滤、聚合与发现

  • 权限校验与用户等级策略

  • 业务规则与参数检验

  • 多级缓冲策略

🧾 介绍

  1. 什么是Spring Cloud Gateway

    Spring Cloud Gateway

网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。

Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,定位于取代Netflix Zuul 1.0。相比Zuul来说,Spring Cloud Gateway提供更优秀的性能,更强大的有功能。

Spring Cloud Gateway是由Web Flux + Netty + Reactor实现的响应式的 API 网关。它不能在传统的 servlet 容器中工作,也不能构 建成war包。

Spring Cloud Gateway旨在为微服务架构提供一种简单且有效的API路由的管理方式,并基于Filter的方式提供网关的基本功能,例如 说安全认证、监控、限流等等。

🔧 准备工作

📦 依赖

       org.springframework.cloud      spring-cloud-starter-gateway          com.alibaba.cloud      spring-cloud-starter-alibaba-nacos-discovery          com.alibaba.cloud      spring-cloud-starter-alibaba-nacos-config          org.springframework.cloud      spring-cloud-starter-loadbalancer          org.projectlombok      lombok      provided  

🧫 配置

 spring:  application:    name: api-gateway  cloud:    nacos:      discovery:        server-addr: localhost:8848    gateway:      discovery:        locator:          enabled: true # 让gateway可以发现nacos中的微服务

📝 核心概念

🚚 路由(route)

路由是网关中最基础的部分,路由信息包括

  • 一个ID

  • 一个目的URI

  • 一组断言工厂

  • 一组Filter组成。

  • 如果断言为真,则说明请求的URL和配置的路由匹配。

✅ 断言(predicates)

Java 8中的断言函数,Spring Cloud Gateway 中的断言函数类型是 Spring 5.0 框架中的Server Web Exchange。

断言函数允许开发者去定义匹配 HttpRequest 中的任何信息,比如请求头和参数等。

🧮 过滤器(Filter)

Spring Cloud Gateway中的filter分为 GatewayFillerGlobalFilter

Filter可以对请求和响应进行处理。

 spring:  cloud:    gateway:      routes: # 路由数组        - id: product_route # 当前路由的唯一标识          uri: lb://product-service  # 请求转发的地址,使用lb负载均衡 + 服务名(也可以直接填写URL)          predicates: # 断言            - Path=/product-serv/** # 判断地址          filters: # 过滤器            - StripPrefix=1 # 转发之前去掉1层路径

📍 工作原理

执行流程大体如下:

  1. Gateway ClientGateway Server发送请求

  2. 请求首先会被HttpWebHandlerAdapter进行提取组装成网关上下文

  3. 然后网关的上下文会传递到DispatcherHandler,它负责将请求分发给RoutePredicateHandlerMapping

  4. RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用

  5. 如果过断言成功,由FilteringWebHandler创建过滤器链并调用

  6. 请求会一次经过**PreFilter-->微服务-->PostFilter**的方法,最终返回响应


🏃 集成Nacos

Gateway集成Nacos 注册和发现服务,通过负载均衡的方式做转发,而不是固定地址URL

省略...


⛩ 路由断言工厂

作用:请求gateway的时候,使用断言对请求进行匹配,如果匹配成功就路由转发,如果匹配失败就返回404 类型:内置,自定义

Spring Cloud Gateway

⏺ 内置断言工厂

Spring Cloud Gateway包括许多内置的断言工厂

  • 基于Datetime类型的断言工厂

    • AfterRoutePredicateFactor: 接收一个日期参数,判断请求日期是否晚于指定日期

    • BeforeRoutePredicateFactory:接收一个日期参数,判断请求日期是否早于指定日期

    • BetweenRoutePredicateFactory:接收两个日期参数,判断请求日期是否在指定时间段内

    • ZonedDateTime.now()

 spring:  cloud:    gateway:      routes:      - id: between_route        uri: https://example.org        predicates:        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

远程地址、Cookie、Header、Host、Method请求方式、Path、Query、路由权重这些断言工厂


📥自定义断言工厂

自定义路由断言工厂需要继承 AbstractRoutePredicateFactory 类,重写apply方法的逻辑。

在apply方法中可以通过exchange.getRequest()拿到ServerHttpRequest对象,从而可以获取到请求的参数、请求方式、请求头等信息。

步骤说明

  1. 必须Spring 组件Bean

  2. 类名必须加上 RoutePredicateFactory 作为结尾(断言名称是类名去掉RoutePredicateFactory部分)

  3. 必须继承 AbstractRoutePredicateFactory

  4. 必须声明静态内部类定义静态内部类的属性作为配置属性接收对应的断言数据

  5. 结合AbstractRoutePredicateFactoryshortcutFieldOrder 进行绑定

  6. 通过apply进行逻辑判断 ,返回new GatewayPredicate()匿名实现类的实现test方法

    • 返回true 匹配成功

    • 返回false 匹配失败


源码案例:

 @Component // 1. 声明Bean // Between + RoutePredicateFactory 2. 断言名称 + RoutePredicateFactory // 3. 继承AbstractRoutePredicateFactory 后面的泛型需要指定一个静态内部类 public class BetweenRoutePredicateFactory extends AbstractRoutePredicateFactory { ​  // 4. 静态内部类  @Validated  public static class Config {  // 4.1 静态内部类属性 (记得get set)  @NotNull  private ZonedDateTime datetime1; ​  @NotNull  private ZonedDateTime datetime2; ​  public ZonedDateTime getDatetime1() {  return datetime1;  }  public Config setDatetime1(ZonedDateTime datetime1) {  this.datetime1 = datetime1;  return this;  }  public ZonedDateTime getDatetime2() {  return datetime2;  }  public Config setDatetime2(ZonedDateTime datetime2) {  this.datetime2 = datetime2;  return this;  }  }  // --------------------------------分割线 -------------------------    /**  * DateTime 1 key.  */  public static final String DATETIME1_KEY = \"datetime1\"; ​  /**  * DateTime 2 key.  */  public static final String DATETIME2_KEY = \"datetime2\"; ​  public BetweenRoutePredicateFactory() {  super(Config.class);  } ​  // 5. 绑定属性,注意顺序  @Override  public List shortcutFieldOrder() {  return Arrays.asList(DATETIME1_KEY, DATETIME2_KEY);  } ​  // 6. apply判断  @Override  public Predicate apply(Config config) {  // ↓ 判断逻辑自定义  Assert.isTrue(config.getDatetime1().isBefore(config.getDatetime2()),  config.getDatetime1() + \" must be before \" + config.getDatetime2());    return new GatewayPredicate() {  @Override  public boolean test(ServerWebExchange serverWebExchange) {  final ZonedDateTime now = ZonedDateTime.now();  return now.isAfter(config.getDatetime1()) && now.isBefore(config.getDatetime2());  } ​  @Override  public Object getConfig() {  return config;  } ​  @Override  public String toString() {  return String.format(\"Between: %s and %s\", config.getDatetime1(), config.getDatetime2());  }  };  } } ---------------------------------------------------yml配置----------------------------------------------------- spring:  cloud:    gateway:      routes:      - id: between_route        uri: https://example.org        predicates:        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

⏳ 过滤器工厂配置

Gateway内置了很多的过滤器工厂,我们通过一些过滤器工厂可以进行一些业务逻辑处理器,比如添加剔除响应头,添加去除参数等

Spring Cloud Gateway

示例 AddRequestHeaderGatewayFilter 过滤工厂:

 spring:  cloud:    gateway:      routes:      - id: add_request_header_route        uri: https://example.org        filters:        - AddRequestHeader=X-Request-red, blue ​ 接受一个name和value参数 将X-Request-red:blue标头添加到所有匹配请求的下游请求标头中 AddRequestHeader能够识别用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用,并在运行时进行扩展。

自定义过滤器工程

继承AbstractNameValueGatewayFilterFactory且我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理。

步骤说明

  1. 必须Spring 组件Bean

  2. 类名必须加上 GatewayFilterFactory 作为结尾(过滤工厂名称是类名去掉GatewayFilterFactory部分)

  3. 必须继承 AbstractNameValueGatewayFilterFactory

  4. 实现 apply(NameValueConfig config)方法

  5. 返回 new GatewayFilter() 匿名实现类

  6. 通过 ServerWebExchange 获取数据,通过过滤链 GatewayFilterChain 将修改数据的数据传递到下一个 源码示例:

 @Component // 1. 注册为Bean // 2. AddRequestHeader + GatewayFilterFactory 过滤器名称 + GatewayFilterFactory // 3. 继承 AbstractNameValueGatewayFilterFactory public class AddRequestHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory { ​    // 4. 实现方法  @Override  public GatewayFilter apply(NameValueConfig config) {  // 5. 返回匿名实现类  return new GatewayFilter() {  @Override  public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {  //   String value = ServerWebExchangeUtils.expand(exchange, config.getValue());  ServerHttpRequest request = exchange.getRequest().mutate()  .headers(httpHeaders -> httpHeaders.add(config.getName(), value)).build(); ​  return chain.filter(exchange.mutate().request(request).build());  } ​  };  } ​ } ​ ​ ---------------------------------------------------------------------------- spring:  cloud:    gateway:      routes:      - id: add_request_header_route        uri: https://example.org        filters:        - AddRequestHeader=X-Request-red, blue

⛓ 全局过滤器配置

局部过滤器和全局过滤器区别: 局部:局部针对某个路由,需要在路由中进行配置 全局:针对所有路由请求,一旦定义就会投入使用

当请求与路由匹配时,过滤 Web 处理程序会将所有 的实例GlobalFilter以及所有路由特定的 的实例添加GatewayFilter到过滤器链中。此组合过滤器链按接口排序org.springframework.core.Ordered,您可以通过实现相应的getOrder()方法来设置接口的排序方式。

GlobalFilter接口和GatewayFilter有一样的接口定义,只不过,`GlobalFilter会作用于所有路由。

Gateway全局过滤器说明

Spring Cloud Gateway 提供了一系列内置的全局过滤器,这些过滤器无需额外配置即可对所有路由生效,负责处理网关的核心功能。以下是主要的内置全局过滤器及其功能(有些不会用到没有例举例如:GlobalLocalResponseCacheGatewayFilter网关缓存):

路由转换过滤器 (自动)

RouteToRequestUrlFilter

  • 优先级10000(优先级较高)

  • 核心功能:将路由信息转换为实际请求的 URL

  • 工作原理

    • 根据路由定义(如服务名、路径)拼接完整的请求 URL

    • 处理 lb:// 等特殊协议(服务发现)和 forward:// 协议(内部转发)

    • 将转换后的 URL 存储在 ServerWebExchange 的属性中


实际的 API 调用触发和执行过滤器 (自动)

NettyRoutingFilter

  • 优先级2147483647

  • 核心功能:处理 HTTP/HTTPS 协议的路由转发

  • 工作原理

    • 使用 Netty 客户端发送请求到目标服务

    • 支持配置连接超时、响应超时等参数

    • 处理请求头、请求体的转发

    • 利用 Netty 的 NIO 特性,高效处理大量并发请求,适合高吞吐量场景

    • 默认转发所有请求头和请求体,确保后端服务能获取完整的客户端请求信息。

NettyRoutingFilter 无需手动配置即可生效,但可通过以下参数调整其行为:

 spring:  cloud:    gateway:      httpclient: # 配置Netty客户端参数        connect-timeout: 1000 # 连接超时时间(毫秒)        response-timeout: 5s   # 响应超时时间        pool:          max-connections: 200 # 最大连接数        ssl: # HTTPS相关配置          use-insecure-trust-manager: false # 是否信任所有证书(生产环境不建议开启)          trusted-x509-certificates: classpath:ssl/trust.pem # 信任的证书

响应返回阶段的过滤器 (自动)

NettyWriteResponseFilter

  • 优先级-1

  • 核心功能其他服务的 API 接口已经被成功调用并返回了响应,处理服务响应的写入

  • 工作原理

    • 直接执行下一个过滤链,等待响应完成、取消、失败回调

    • ServerWebExchange 中获取后端服务返回的原始响应(HttpResponse

    • 将响应头(如 Content-LengthCache-Control)复制到网关的 ServerHttpResponse 中。

    • 将响应体通过 Netty 的 Channel 写入客户端连接,完成数据返回。

    • 处理响应的编码(如 gzip 解压,若后端服务返回压缩数据)或其他格式转换。


网关内部 API 转发过滤器 (自动)

ForwardRoutingFilter

  • 优先级2147483647

  • 核心功能:处理 forward:// 协议的路由

  • 工作原理

    • 当路由匹配且 uriforward:// 开头时,ForwardRoutingFilter 被激活。

    • 解析 forward:// 后的路径(如 forward:/actuator/health 解析为 /actuator/health)。

    • 构建新的请求,将路径重写为解析后的内部路径。

    • 通过 DispatcherHandler 将请求转发到网关自身的对应端点。

    • 内部端点处理请求后,响应会直接返回给客户端,无需经过外部服务调用流程。

  • 应用场景

    • 将请求转发到网关自身的其他端点(如 /actuator 监控端点)

    • 实现网关内部的请求转发,无需通过网络


网关内部路径过滤器 (自动)

ForwardPathFilter

  • 优先级:0

  • ForwardRoutingFilter`ForwardPathFilter区别:

  1. ForwardPathFilter:路径调整器

    • 作用:专门处理本地转发的路径格式问题,确保请求路径能匹配网关内部的处理器(如 @Controller 接口)。

    • 举例:当路由配置为 Path=/api/internal/**uri=forward:/// 时,客户端请求 /api/internal/health 会被它调整为 /internal/health(移除路由前缀 /api),以便匹配网关内部的 /internal/health 接口。

    • 本质:解决 “外部请求路径” 与 “网关内部接口路径” 的格式差异,属于转发前的 “路径预处理”。

  2. ForwardRoutingFilter:转发执行者

    • 作用:在路径调整完成后,负责将请求实际转发到网关内部的处理机制(如 Spring MVC/WebFlux 的控制器),是本地转发的 “最终执行者”。

    • 工作方式:它会拦截 uriforward:// 开头的路由,将请求交给网关自身的 DispatcherHandler(Spring Web 的核心处理器),由其匹配对应的控制器方法并处理请求。

    • 本质:触发本地请求的处理流程,替代 “向外部服务发送请求” 的逻辑。


API 调用触发和执行过滤器(替代Netty需手动配置)

WebClientHttpRoutingFilter

排除了 reactor-netty和引入了 spring-web 依赖(提供 WebClient 支持)

才会生效

功能和NettyRoutingFilter差不多

  • 优先级2147483647

  • 核心功能:基于 Spring WebClient 的 HTTP 路由转发

  • 特点

    • 作为 NettyRoutingFilter 的替代方案

    • 适用于非 Netty 环境(如 Servlet 容器)

    • 支持响应式编程模型


负载均衡过滤器 (自动)

ReactiveLoadBalancerClientFilter

基于响应式编程模型的负载均衡过滤器,主要用于处理 lb:// 协议的服务路由,实现服务发现与负载均衡功能,是微服务架构中网关实现服务动态路由的关键组件。

需要依赖:spring-cloud-starter-loadbalancer

  • 优先级10150

  • 核心功能

    • 响应式负载均衡过滤器(默认使用轮询策略,可自定义)

    • 处理 lb:// 协议的服务路由

    • 替换服务名为实际地址

  • 工作原理:

    与 Eureka、Nacos、Consul 等服务注册中心配合,自动感知服务实例的上下线,无需手动修改路由配置。

    • 当请求匹配到 urilb:// 协议的路由时,ReactiveLoadBalancerClientFilter 被激活。

    • 从路由 uri 中提取服务名(如从 lb://user-service 中提取 user-service)。

    • 通过响应式负载均衡器(ReactiveLoadBalancer)获取该服务的可用实例列表。

    • 应用负载均衡策略(如轮询、随机、权重等)选择一个服务实例。

    • 将路由的目标地址替换为选中实例的实际地址(IP: 端口)。

    • 将修改后的地址存入 ServerWebExchange 中,传递给后续过滤器(如 NettyRoutingFilter)进行请求转发。

  • 特点

    • 基于响应式编程模型的负载均衡实现

    • 与 Spring Cloud LoadBalancer 的响应式 API 集成

    • 支持更灵活的负载均衡策略配置


收集和暴露网关的核心指标数据过滤器 (自动)

GatewayMetricsFilter

  • 优先级:0

  • 工作流程:

    • 直接执行下一个过滤链,等待成功或者失败的回调

  • 核心功能

    • 收集关键指标

      • 记录请求处理的耗时(从请求进入网关到完成处理的时间)

      • 统计不同路由的请求数量

      • 记录请求的响应状态码分布(如 200、404、500 等)

      • 跟踪请求的处理结果(成功 / 失败)

    • 整合监控系统

      • 将收集的指标数据暴露给 Spring Boot Actuator 的/metrics端点

      • 支持与 Prometheus、Graphite 等监控系统集成

      • 便于通过 Grafana 等工具可视化网关性能指标

    • 支持定制化标签

      • 可以为指标添加自定义标签(如路由 ID、服务名称等)

      • 帮助更精细地筛选和分析不同维度的指标数据

  • 使用方式

     org.springframework.boot    spring-boot-starter-actuator       io.micrometer    micrometer-registry-prometheus 
 # management 是Spring Boot Actuator的配置根节点,用于配置应用监控和管理功能 management:  # endpoints 配置各种actuator端点  endpoints:    # web 配置web相关的端点设置    web:      # exposure 配置端点暴露设置      exposure:        # include 指定需要暴露的端点,这里是暴露health,info,metrics,prometheus四个端点        # health: 健康检查端点,用于检查应用健康状态        # info: 信息端点,显示应用信息        # metrics: 指标端点,提供应用运行时指标数据        # prometheus: Prometheus端点,提供Prometheus格式的指标数据        include: health,info,metrics,prometheus ​  # endpoint 配置特定端点的设置  endpoint:    # prometheus 配置Prometheus端点    prometheus:      # enabled 设置Prometheus端点是否启用,这里设置为true表示启用      enabled: true ​  # prometheus 配置Prometheus相关的指标导出设置  prometheus:    # metrics 配置指标相关设置    metrics:      # export 配置指标导出设置      export:        # enabled 设置是否启用Prometheus指标导出,这里设置为true表示启用        enabled: true

使用 Grafana 连接 Prometheus

下载链接:Download Grafana | Grafana Labs

未完.... TODO

  • 典型场景

  • 监控网关吞吐量、响应时间分布

  • 统计各路由的请求成功率

  • 与 Prometheus+Grafana 搭建监控面板

  • 数据指标:包含gateway.requests指标,记录状态码、路由 ID、方法等维度


缓存请求体数据过滤器 (自动)

AdaptCachedBodyGlobalFilter

过滤器逻辑中存在获取、解析、处理ServerHttpRequest.getBody()返回的数据流的操作就会触发这个过滤器

默认值为 256KB 超过了默认的大小会报异常:DataBufferLimitException.class

  • 优先级:-2147483648 + 1000

  • 核心功能

    • 缓存请求体:

      • 对于包含请求体的请求(如 POST、PUT 等),将原始请求体内容缓存到ServerWebExchange的属性中

      • 避免后续过滤器或路由处理逻辑因重复读取请求体而导致的异常(如IllegalStateException: Only one connection receive subscriber allowed

    • 适配请求体格式:

      • 将原始请求体包装为CachedBodyOutputMessage,允许后续组件通过DataBuffer的形式多次读取

      • 支持对不同类型的请求体(如 JSON、表单数据等)进行统一处理

    • 自动触发条件

      • 当网关中存在需要多次读取请求体的组件(如请求体日志记录、参数验证、签名验证等过滤器)时,该过滤器会自动生效

      • 通常与ReadBodyPredicateFactory等需要访问请求体的组件配合使用

  • 使用方式:自动生效,无需配置。使用以下方式可以配置缓存大小(需要禁用)

 spring:  codec:    max-in-memory-size: 512KB # 调整最大缓存大小
  • 典型场景

  • 需要多次读取请求体的场景(如日志记录 + 参数校验)

  • 请求体签名验证

  • 请求内容审计

  • 注意:会增加内存消耗,大请求体场景需谨慎


清理缓存的请求体数据 (自动)

RemoveCachedBodyFilter

  • 优先级:-2147483648

  • 使用方式:自动生效,无需配置

  • 核心功能

    • 清理缓存的请求体:当请求处理流程完成(无论成功或失败)后,移除AdaptCachedBodyGlobalFilter缓存的请求体数据(即CachedBodyOutputMessage对象),释放占用的内存资源。

    • 防止内存泄漏:由于请求体缓存(尤其是大请求体)会占用堆内存,若不及时清理,可能导致高并发场景下的内存溢出,该过滤器通过主动清理确保资源释放。

  • 工作流程

    • 执行让下一个过滤链执行,等待完成所有过滤链之后回调

    • 回调之后清理缓存

  • 典型场景

  • 清理 AdaptCachedBodyGlobalFilter 缓存的请求体

  • 防止内存泄漏,尤其在处理大请求体时

  • 特点:在响应返回阶段执行,确保资源及时释放


处理 WebSocket 协议过滤器

WebSocketRoutingFilter

在 Spring Cloud Gateway 中,WebSocketRoutingFilter 是专门用于处理 WebSocket 协议请求路由的内置过滤器,其核心作用是将客户端的 WebSocket 连接请求转发到后端对应的 WebSocket 服务,实现网关对 WebSocket 流量的代理和路由能力。

  • 优先级: 2147483646

  • 核心功能

    • WebSocket 协议路由 专门处理ws://wss://协议的请求,根据网关配置的路由规则(如路径匹配、断言条件等),将 WebSocket 连接请求转发到对应的后端服务实例。

    • 连接握手代理 代理客户端与后端服务之间的 WebSocket 握手过程:

      • 接收客户端的 WebSocket 升级请求(包含Upgrade: websocket等头信息)

      • 向后端服务发起对应的握手请求

      • 完成握手后,在客户端与后端服务之间建立双向的数据转发通道

    • 全双工通信支持 建立连接后,负责在客户端和后端服务之间双向转发 WebSocket 消息(文本消息、二进制消息等),保持实时通信的连续性。

  • 使用方式

 spring:  cloud:    gateway:      routes:        - id: websocket-route          uri: ws://localhost:8081 # 或wss://          predicates:            - Path=/ws/**
  • 典型场景

  • 代理 WebSocket 服务(如实时聊天、消息推送)

  • 实现 WebSocket 连接的负载均衡(配合 lb:// 协议)

  • 注意:需要确保网关与后端服务都支持 WebSocket


不使用负载均衡过滤器 (自动)

NoLoadBalancerClientFilter

  • 优先级:10150

  • 核心功能:

    • 直接处理服务名路由 当路由的 uri 是具体的 HTTP/HTTPS 地址(如 http://localhost:8081https://api.example.com)时,该过滤器会直接使用配置的 uri 进行请求转发,无需通过服务发现或负载均衡器解析地址。

    • 适配无负载均衡环境 当项目中没有引入负载均衡依赖(如 spring-cloud-starter-loadbalancer 或 Ribbon)时,NoLoadBalancerClientFilter 会替代负载均衡相关的过滤器(如 LoadBalancerClientFilter),确保路由转发逻辑正常执行,避免因缺少负载均衡组件而导致的转发失败。

    • 保持基础路由能力 即使没有负载均衡,也能通过静态配置的 uri 实现请求转发,支持网关的基本路由功能(如路径匹配、过滤器链执行等)。

  • 生效条件

    • 仅当路由的 uri 不是负载均衡协议(即不以 lb:// 开头),且项目中未启用负载均衡组件时,该过滤器才会生效。

  • 使用场景

    NoLoadBalancerClientFilter 典型的使用场景包括:

    • 网关仅需转发到固定的单一服务实例(如测试环境的单体服务)。

    • 项目架构中不使用服务发现和负载均衡(如静态路由配置)。

    • 临时绕过负载均衡,直接路由到某个具体实例进行问题排查。

使用示例:

 spring:  cloud:    gateway:      routes:        - id: direct_route          uri: http://localhost:8081 # 具体的服务地址,非服务名          predicates:            - Path=/api/**          filters:            - AddRequestHeader=X-Source, gateway

网关响应资源处理过滤器(自动)

WebClientWriteResponseFilter

  • 优先级:-1

主要目的是维护网关本身的稳定性和防止资源泄漏

  • 核心功能

    • 资源清理和防止内存泄漏

  • 工作流程:

    • 直接执行下一个过滤链,在发生错误和成功之后回调

      • 错误的时候,返回空响应体

      • 成功时候整理响应体(取消的时候也返回空响应体)


内置全局过滤器的执行流程


客户端网关入口请求预处理路由转发响应处理后端服务/内部端点发起请求 (HTTP/WS/HTTPS)初始化请求上下文高优先级过滤器(数值越小越先执行)1. RemoveCachedBodyFilter[优先级: 最高]▸ 等待回调2. AdaptCachedBodyGlobalFilter[优先级: 最高+1000]▸ 缓存请求体数据3. NettyWriteResponseFilter[优先级: -1]▸ 等待回调4. WebClientWriteResponseFilter[优先级: -1]▸ 等待回调5. RouteToRequestUrlFilter[优先级: 10000]▸ 转换路由为实际URL6. 负载均衡处理▸ ReactiveLoadBalancerClientFilter [10150]▸ 或 NoLoadBalancerClientFilter [10150]7. ForwardPathFilter[优先级: 0]▸ 调整内部转发路径8. GatewayMetricsFilter[优先级: 0]▸ 等待回调移交请求处理权路由执行阶段9. 协议路由选择▸ WebSocketRoutingFilter [最低 - 1]▸ 或 NettyRoutingFilter [最低]▸或ForwardRoutingFilter [最低]▸ 或 WebClientHttpRoutingFilter [最低]转发请求到目标服务返回处理结果移交响应处理权响应返回阶段10. WebClientWriteResponseFilter[优先级: -1]▸ (回调)清理响应资源11. NettyWriteResponseFilter[优先级: -1]▸ (回调)处理响应写入客户端12. GatewayMetricsFilter[优先级: 0]▸ (回调)完成监控指标记录13. RemoveCachedBodyFilter[优先级: -2147483648]▸ (回调)最终清理请求体缓存返回响应结果客户端网关入口请求预处理路由转发响应处理后端服务/内部端点

内置过滤器的配置方式

虽然内置全局过滤器无需显式配置,但可以通过配置文件调整其行为:

 spring:  cloud:    gateway:      httpclient:        connect-timeout: 1000  # 配置Netty客户端连接超时        response-timeout: 5s   # 配置响应超时      loadbalancer:        use404: true  # 当服务实例不存在时返回404

自定义全局过滤器

配置步骤

  1. 继承 GlobalFilter (可以继承 Ordered来控制执行顺序)

  2. 实现 filter(ServerWebExchange exchange, GatewayFilterChain chain)方法

  3. 返回chain.filter(exchange) 执行下一个过滤链

 @Bean public GlobalFilter customFilter() {    return new CustomGlobalFilter(); } ​ public class CustomGlobalFilter implements GlobalFilter, Ordered { ​    @Override    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {        log.info(\"custom global filter\");        return chain.filter(exchange);    } ​    @Override    public int getOrder() {        return -1;    } } ​ ​

🧾自定义网关内部API

通过 Spring WebFlux 自定义网关内部端点(因为 Gateway 基于 WebFlux 响应式编程),用于实现网关自身的业务逻辑(如静态资源服务、简单计算等)。

 import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.annotation.RestController; import reactor.core.publisher.Mono; ​ @RestController public class GatewayGatewayInternalController { ​    // 自定义内部端点:返回网关版本信息    @GetMapping(\"/gateway/version\")    public Mono getGatewayVersion() {        return Mono.just(\"Gateway Version: 2.2.9.RELEASE\");    } ​    // 自定义内部端点:简单计算    @GetMapping(\"/gateway/add/{a}/{b}\")    public Mono add(@PathVariable int a, @PathVariable int b) {        return Mono.just(a + b);    } }

通过 ForwardRoutingFilter 映射自定义端点

 spring:  cloud:    gateway:      routes:        # 将 /internal/version 映射到网关内部的 /gateway/version        - id: internal-version-route          uri: forward:/gateway/version # 使用 forward: 进行网关内部转发          predicates:            - Path=/internal/version                   # 将 /internal/add 映射到网关内部的 /gateway/add        - id: internal-add-route          uri: forward:/gateway/add/{a}/{b}          predicates:            - Path=/internal/add/{a}/{b}