Spring Cloud Gateway 的执行链路详解
🎯 核心目标
明确 Spring Cloud Gateway 的请求处理全过程(从接收到请求 → 到转发 → 到返回响应),方便你在合适的生命周期节点插入你的逻辑。
🧱 核心执行链路图(执行顺序)
┌──────────────┐
│ 客户端请求 │
└────┬─────────┘
↓
┌────┴─────────────┐
│ Netty HttpServer │ ←→ Reactor Netty(非阻塞)
└────┬─────────────┘
↓
┌────┴────────────┐
│ HttpRoutePredicateEvaluator │ 路由匹配
└────┬────────────┘
↓
┌────┴────────────┐
│ GlobalFilter Chain │ ← 【你做定制的核心入口】
│ ├── GlobalFilter (Ordered)
│ ├── CustomFilter
│ └── FilterChain
└────┬────────────┘
↓
┌────┴────────────┐
│ WebClient 调用目标服务 │(负载均衡、路由转发)
└────┬────────────┘
↓
┌────┴────────────┐
│ 响应处理(过滤器链倒序) │
└────────────┬────┘
↓
客户端收到响应
🔄 Gateway 核心处理流程分阶段讲解
🔹 1. 请求接入:Netty 接收
- Gateway 使用 Reactor Netty 构建 Server,所有请求是异步 + 非阻塞处理。
- 请求通过
HttpServer
被接收并封装成ServerWebExchange
对象(封装 request + response + 路由信息 + 上下文等)。
🔹 2. Route 匹配阶段(断言匹配)
配置文件中的路由定义,如:
spring:
cloud:
gateway:
routes:
- id: user_route
uri: http://user-service
predicates:
- Path=/api/user/**
这一步是通过 RoutePredicateHandlerMapping
完成:
✅ 判断当前请求路径是否匹配配置中的 predicates
📌 你可以实现
RoutePredicateFactory
来定制更复杂的匹配规则,例如 IP、请求头、时间段等
🔹 3. 全局过滤器链(GlobalFilter)执行阶段
这是你进行自定义操作的核心切入点!
内置常用过滤器有:
过滤器类名 | 作用 | 顺序(order) |
---|---|---|
RemoveRequestHeaderGatewayFilter | 删除请求头 | -1 |
AddRequestHeaderGatewayFilter | 添加请求头 | 0 |
RetryGatewayFilter | 自动重试 | -2 |
RequestRateLimiterGatewayFilter | 限流(结合 Redis) | -10 |
HystrixGatewayFilter | 熔断降级 | -100 |
你也可以实现自己的 GlobalFilter
或 GatewayFilterFactory
:
示例:自定义 GlobalFilter
@Component
@Order(-1) // 顺序越小越先执行
public class AuthGlobalFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (!StringUtils.hasText(token) || !checkToken(token)) {
// 拦截请求,返回 401
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange); // 放行
}
}
🔹 4. 网关调用下游服务(转发阶段)
- 实际调用目标服务(通过
WebClient
发出请求) - 如果配置了
lb://
前缀,会使用 Spring Cloud LoadBalancer 做负载均衡(Nacos、Eureka 都支持)
uri: lb://order-service
🔹 5. 响应返回时的处理(倒序执行 Filter)
在响应返回时,全局过滤器链会逆序执行,可以在这里做一些响应增强:
- 添加响应头
- 日志记录(返回码、耗时)
- 数据脱敏
- 响应体改写(结合缓存)
示例:记录响应耗时
@Component
@Order(1)
public class TimeLogFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
long start = System.currentTimeMillis();
return chain.filter(exchange).then(
Mono.fromRunnable(() -> {
long cost = System.currentTimeMillis() - start;
System.out.println("接口请求耗时:" + cost + "ms");
})
);
}
}
🔧 常见自定义操作建议位置对照表
功能 | 推荐实现方式 | 说明 |
---|---|---|
请求日志记录 | GlobalFilter | 获取 request 信息,记录 URI/参数/IP |
参数校验(如签名) | GlobalFilter | 拦截非法请求 |
JWT 鉴权 | GlobalFilter | 可选使用 Reactor 模式解析 token |
限流(IP/QPS) | Redis + 自定义 Filter | 或使用 Spring 官方限流 Filter |
熔断降级 | Resilience4j/Hystrix | 可集成入 Gateway Filter |
黑名单拦截 | GlobalFilter + Redis | 校验 IP 是否在黑名单 |
响应体改写 | RewriteResponseBodyFilter | 需要缓存响应流 |
请求体改写 | RewriteRequestBodyFilter | 非常规操作,需 cache request body |
📌 注意事项:Netty + 响应式陷阱
Spring Cloud Gateway 是响应式编程,与传统 Servlet 不一样:
注意点 | 说明 |
---|---|
Request Body 只能读取一次 | 需要使用 CachedBodyOutputMessage 缓存 |
Response 体也只能写一次 | 修改响应需用 BodyInserter |
操作是异步链式的 | 推荐使用 Mono.defer() 、then() 等操作链 |
使用 @Order 控制顺序 | 值越小越早执行,如认证应在最前面执行 |
🎁 Bonus:完整请求链源码入口参考(Spring Cloud Gateway)
模块 | 类名 | 说明 |
---|---|---|
spring-cloud-gateway | GatewayAutoConfiguration | 自动装配 |
RoutePredicateHandlerMapping | 匹配路由 | |
FilteringWebHandler | 核心过滤链执行器 | |
GlobalFilter | 全局过滤器接口 | |
GatewayFilterFactory | 局部路由过滤器工厂接口 |