服务网关:解密 Spring Cloud Gateway 过滤器链执行机制
在 Spring Cloud Gateway 微服务网关中,如果路由断言(Route Predicate)解决了“请求应该发给谁”的问题,那么**网关过滤器(Gateway Filter)**则决定了“请求在转发前和响应返回后应该怎么被加工”。
与传统的 Servlet 过滤器不同,Spring Cloud Gateway 是基于 **Spring WebFlux (Project Reactor)** 响应式流构建的。其核心过滤器链(GatewayFilter Chain)采用非阻塞的响应式管道机制,通过巧妙地返回 Mono<Void>,在单线程事件循环中完美达成了类似 Servlet 过滤器的 **Pre(前置拦截)** 和 **Post(后置拦截)** 流程。
本文将系统拆解网关过滤器链的响应式执行原理、前置与后置拦截的核心分工、以及自定义网关过滤工厂的开发实战。
一、 核心范式:Pre 拦截与 Post 拦截
网关过滤器在一个请求的完整生命周期中,通常在转发前后承担完全不同的物理职责:
| 过滤器拦截阶段 | 执行物理时机 | 经典业务场景 | Java 代码书写规约 |
|---|---|---|---|
| Pre (前置拦截) | 在网关将请求通过 HTTP 客户端转发给后端微服务**之前**。 | 鉴权拦截、请求体改写、流量计数、黑名单过滤。 | 在调用 chain.filter(exchange) **之前**编写的逻辑。 |
| Post (后置拦截) | 在后端微服务响应返回给网关、且网关准备写回给客户端**之时**。 | 修改响应头、记录调用时长、响应体加密、跨域 Header 补全。 | 在 chain.filter(exchange).then(Mono.fromRunnable(...)) 中编写的逻辑。 |
二 响应式过滤器链执行流水线拓扑
当一个外部请求涌入网关过滤器链时,Pre 与 Post 拦截逻辑的响应式流转拓扑如下:
[ 外部客户端 HTTP 请求 ]
│
▼ (Pre 阶段: 从 Filter 1 依次向后执行)
[ Filter 1: Pre 拦截 ] ──> (比如校验 Token)
│
▼
[ Filter 2: Pre 拦截 ] ──> (比如添加自定义 Header)
│
▼ (通过 Netty 发起路由转发)
[ Routing Filter ──> 后端订单微服务 ──> 拿到后端响应 ]
│
▼ (Post 阶段: 反向从 Filter 2 依次向前执行)
[ Filter 2: Post 拦截 ] ◄── (比如计算本次调用耗时)
│
▼
[ Filter 1: Post 拦截 ] ◄── (比如强改 HTTP 响应状态码)
│
▼
[ 写回客户端响应 ]
---三、 代码实战:编写自定义网关过滤器工厂
以下代码展示了如何编写一个自定义的过滤器工厂(GatewayFilterFactory),用于在 Pre 阶段统计并限制请求报文的大小,并在 Post 阶段输出此次请求的物理耗时:
1. 自定义过滤器工厂类(Java Layer)
package com.company.infra.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import java.util.Collections;
import java.util.List;
/**
* 自定义流量耗时监控过滤器工厂
* 命名规约:类名必须以 "GatewayFilterFactory" 结尾
*/
@Component
public class MonitorTimeGatewayFilterFactory extends AbstractGatewayFilterFactory<MonitorTimeGatewayFilterFactory.Config> {
public MonitorTimeGatewayFilterFactory() {
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList("enabled");
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
if (!config.isEnabled()) {
return chain.filter(exchange);
}
// 1. 【Pre 前置拦截逻辑】:记录进入网关的初始时间戳
long startTime = System.currentTimeMillis();
// 2. 将请求向后派发,并通过 then() 挂载响应式 Post 拦截回调
return chain.filter(exchange).then(
Mono.fromRunnable(() -> {
// 3. 【Post 后置拦截逻辑】:计算并输出后端服务响应的物理耗时
long endTime = System.currentTimeMillis();
long executeTime = endTime - startTime;
System.out.println("[Gateway Monitor] 请求: " + exchange.getRequest().getURI().getPath()
+ " 执行完毕,物理耗时: " + executeTime + "ms");
})
);
};
}
/**
* 配置实体类
*/
public static class Config {
private boolean enabled;
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
}
}
2. 在 application.yml 路由中装配自定义过滤器
spring:
cloud:
gateway:
routes:
- id: order-service-route
uri: lb://order-service
predicates:
- Path=/api/v1/orders/**
filters:
# 引入自定义过滤器工厂,传入配置参数 enabled=true
- name: MonitorTime
args:
enabled: true
---四、 总结
Spring Cloud Gateway 的响应式网关过滤器链执行机制,是实现微服务边界流控、安全审计与拓扑监控的“核心控制总线”。
It 通过**基于 Reactor Mono 模型的链式调用,在彻底摒弃了 Servlet 传统线程阻塞模型的同时,实现了完美的前后置逻辑穿插编排;并依靠可配置的 FilterFactory 机制,向研发人员提供了高度自由的网关管道扩展能力**。掌握这套响应式过滤器执行机理与自定义 FilterFactory 编写规范,是构建高性能企业级安全API网关、实现微服务网边流量精细化拦截控制 of 核心看家本领!
本站所有文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。



暂无评论
还没有人评论过本文,快来发表你的高见吧!