Spring Cloud Gateway_Spring Cloud Gateway routing configuration example
# Spring Cloud Gateway资料
所谓的API网关,指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑 可以在这里实现,诸如认证、鉴权、监控、路由转发等等。
全局性流控
日志统计
防止SQL注入
防止Web攻击
屏蔽工具扫描
黑白名单
证书/加解密处理
服务级别流控
服务降级与熔断
路由与负载均衡、灰度策略
服务过滤、聚合与发现
权限校验与用户等级策略
业务规则与参数检验
多级缓冲策略
🧾 介绍
-
什么是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分为 GatewayFiller
和GlobalFilter
。
Filter可以对请求和响应进行处理。
spring: cloud: gateway: routes: # 路由数组 - id: product_route # 当前路由的唯一标识 uri: lb://product-service # 请求转发的地址,使用lb负载均衡 + 服务名(也可以直接填写URL) predicates: # 断言 - Path=/product-serv/** # 判断地址 filters: # 过滤器 - StripPrefix=1 # 转发之前去掉1层路径
📍 工作原理
执行流程大体如下:
-
Gateway Client
向Gateway Server
发送请求 -
请求首先会被
HttpWebHandlerAdapter
进行提取组装成网关上下文 -
然后网关的上下文会传递到
DispatcherHandler
,它负责将请求分发给RoutePredicateHandlerMapping
-
RoutePredicateHandlerMapping
负责路由查找,并根据路由断言判断路由是否可用 -
如果过断言成功,由
FilteringWebHandler
创建过滤器链并调用 -
请求会一次经过
**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
对象,从而可以获取到请求的参数、请求方式、请求头等信息。
步骤说明
-
必须Spring 组件Bean
-
类名必须加上
RoutePredicateFactory
作为结尾(断言名称是类名去掉RoutePredicateFactory
部分) -
必须继承
AbstractRoutePredicateFactory
-
必须声明静态内部类、定义静态内部类的属性作为配置属性接收对应的断言数据
-
结合
AbstractRoutePredicateFactory
的shortcutFieldOrder
进行绑定 -
通过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管理。
步骤说明
-
必须Spring 组件Bean
-
类名必须加上
GatewayFilterFactory
作为结尾(过滤工厂名称是类名去掉GatewayFilterFactory
部分) -
必须继承
AbstractNameValueGatewayFilterFactory
-
实现
apply(NameValueConfig config)
方法 -
返回
new GatewayFilter()
匿名实现类 -
通过
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-Length
、Cache-Control
)复制到网关的ServerHttpResponse
中。 -
将响应体通过 Netty 的
Channel
写入客户端连接,完成数据返回。 -
处理响应的编码(如
gzip
解压,若后端服务返回压缩数据)或其他格式转换。
-
网关内部 API
转发过滤器 (自动)
ForwardRoutingFilter
-
优先级:
2147483647
-
核心功能:处理
forward://
协议的路由 -
工作原理:
-
当路由匹配且
uri
以forward://
开头时,ForwardRoutingFilter
被激活。 -
解析
forward://
后的路径(如forward:/actuator/health
解析为/actuator/health
)。 -
构建新的请求,将路径重写为解析后的内部路径。
-
通过
DispatcherHandler
将请求转发到网关自身的对应端点。 -
内部端点处理请求后,响应会直接返回给客户端,无需经过外部服务调用流程。
-
-
应用场景:
-
将请求转发到网关自身的其他端点(如
/actuator
监控端点) -
实现网关内部的请求转发,无需通过网络
-
网关内部路径过滤器 (自动)
ForwardPathFilter
-
优先级:
0
-
ForwardRoutingFilter
和`ForwardPathFilter
区别:
-
ForwardPathFilter
:路径调整器-
作用:专门处理本地转发的路径格式问题,确保请求路径能匹配网关内部的处理器(如
@Controller
接口)。 -
举例:当路由配置为
Path=/api/internal/**
且uri=forward:///
时,客户端请求/api/internal/health
会被它调整为/internal/health
(移除路由前缀/api
),以便匹配网关内部的/internal/health
接口。 -
本质:解决 “外部请求路径” 与 “网关内部接口路径” 的格式差异,属于转发前的 “路径预处理”。
-
-
ForwardRoutingFilter
:转发执行者-
作用:在路径调整完成后,负责将请求实际转发到网关内部的处理机制(如 Spring MVC/WebFlux 的控制器),是本地转发的 “最终执行者”。
-
工作方式:它会拦截
uri
以forward://
开头的路由,将请求交给网关自身的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 等服务注册中心配合,自动感知服务实例的上下线,无需手动修改路由配置。
-
当请求匹配到
uri
为lb://
协议的路由时,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:8081
或https://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
自定义全局过滤器
配置步骤
-
继承
GlobalFilter
(可以继承Ordered
来控制执行顺序) -
实现
filter(ServerWebExchange exchange, GatewayFilterChain chain)
方法 -
返回
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}