Spring Cloud Gateway 是什么

Spring Cloud Gateway 是 Spring 官方基于 Spring WebFlux(底层默认使用 Netty)构建的 API 网关。它在 2.x 时代替代了不再维护的 Zuul 1.x,成为 Spring Cloud 微服务体系中的标准网关方案。它是一个非阻塞、响应式的网关,完全异步,天然适配高并发场景。

核心特点:它不是基于 Servlet 容器(如 Tomcat),而是运行在 Netty 之上,因此它不阻塞调用线程,能更好地利用系统资源,适合作为微服务入口承担海量请求。

Gateway 的核心模型是:

  • Route(路由):网关的基本构建块,包含 ID、目标 URI、断言集合、过滤器集合。
  • Predicate(断言):匹配 HTTP 请求的条件,比如路径、Header、参数等。
  • Filter(过滤器):对请求或响应进行修改、加工,分为 GatewayFilter(局部)和 GlobalFilter(全局)。

可以实现哪些功能

Spring Cloud Gateway 不只是一个转发请求的工具,它提供了丰富的内置能力,几乎覆盖网关层所有常见需求:

  1. 动态路由与负载均衡
  • 与注册中心(Eureka、Nacos、Consul)集成,通过 lb://service-name 实现服务发现与客户端负载均衡。
  • 可根据路径、域名、请求头等灵活路由到不同服务。
  1. 断言工厂(Predicate)
  • 基于 PathHostMethodHeaderQueryCookieRemoteAddrWeight 等条件匹配。
  • 可结合 Before/After/Between 时间断言控制路由时效。
  1. 过滤器(GatewayFilter)
  • 请求修改:添加/删除请求头、参数、路径重写(RewritePath)、重定向。
  • 响应修改:添加/删除响应头、修改响应体(需注意内存)。
  • 熔断降级:集成 Resilience4J 或 Hystrix(已停更,推荐 Resilience4J)实现熔断,降级时返回兜底响应。
  • 限流:基于 RequestRateLimiter,使用令牌桶算法,底层依赖 Redis 实现分布式限流。
  • 重试Retry 过滤器可针对特定状态码或异常进行重试。
  • 跨域(CORS):直接在网关层统一处理跨域。
  • 安全认证:通过全局过滤器实现 Token 校验、OAuth2 集成,或与 Spring Security 联动。
  • 请求缓存/透传:如 ReadBody 过滤器提前读取请求体,供后续使用(小心内存)。
  1. 全局过滤器与自定义过滤器
  • 可编写 GlobalFilter 实现全局鉴权、日志记录、链路追踪(与 Sleuth 结合生成 TraceId)。
  • 自定义 GatewayFilterFactory 实现特定业务逻辑,比如加解密。
  1. 灰度发布与权重路由
  • 通过 Weight 断言实现流量按比例转发到不同服务版本,完成金丝雀发布。
  1. 聚合网关
  • 可配置多个 Route,将不同前端团队的路由聚合到一个入口。

如何使用

基于 Spring Cloud 2021.0.x(对应 Boot 2.6.x~2.7.x),依赖 spring-cloud-starter-gateway

引入依赖

1
2
3
4
5
6

<dependency>
org.springframework.cloud
spring-cloud-starter-gateway
</dependency>

配置文件方式(最常用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service # 通过注册中心负载均衡
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1 # 转发前去掉第一段路径
- id: order-service
uri: http://localhost:8081
predicates:
- Host=order.example.com
- Query=legacy, true
filters:
- AddRequestHeader=X-From-Gateway, true
default-filters:
- AddResponseHeader=X-Response-Default, 1

Java DSL 方式配置

1
2
3
4
5
6
7
8
9
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/get")
.uri("http://httpbin.org"))
.route("host_route", r -> r.host("*.myhost.org")
.uri("http://httpbin.org"))
.build();
}

自定义过滤器

实现 GatewayFilterFactoryGlobalFilter

1
2
3
4
5
6
7
8
9
10
11
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
// 校验逻辑
return chain.filter(exchange);
}
@Override
public int getOrder() { return -100; }
}

启用注册中心与负载均衡

依赖 spring-cloud-starter-loadbalancer(默认),启动类无需额外注解,只需添加注册中心客户端依赖即可使用 lb://

结合 Resilience4J 熔断

1
2
3
4
5
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/fallback

优点

  1. 异步非阻塞,性能高
  • 基于 Netty + WebFlux,线程开销极小,单机能承载数万并发连接,远超基于 Servlet 的 Zuul 1.x。
  1. 与 Spring 生态深度集成
  • 无缝对接注册中心、配置中心、Spring Security、Sleuth、Micrometer,开发效率高。
  1. 丰富的内置谓词和过滤器
  • 开箱即用,满足大部分场景,减少重复造轮子。
  1. 编程模型统一且响应式
  • 使用 Project Reactor 的 Mono/Flux,能灵活处理异步流,与整个 WebFlux 体系一致。
  1. 活跃的社区与维护
  • 作为 Spring Cloud 子项目,持续迭代,跟随 Spring Boot 生命周期。

缺点

  1. WebFlux 学习曲线
  • 对不熟悉响应式编程的开发者来说,调试难,堆栈信息不直观,容易写出阻塞代码。
  1. 不支持 Servlet API
  • 很多依赖 Servlet 的传统库(如 Hystrix 仪表盘、一些安全库)无法直接使用,需寻找反应式替代品。
  1. 内存与 CPU 消耗
  • 虽然没有线程阻塞,但大量使用异步对象可能导致内存分配压力,不合理的过滤器链可能造成内存泄漏。
  1. 功能复杂度下的配置膨胀
  • 配置过多时,yaml 可读性下降,动态路由的管理需要借助数据库+事件刷新(如使用 Nacos 配置中心),略显复杂。
  1. 网关层业务逻辑禁忌
  • 过滤器中如果塞入过多业务逻辑,会破坏网关的纯粹性,让网关变得臃肿难维护。

潜在风险与注意事项

潜在风险

  • 阻塞调用风险:在过滤器中使用阻塞操作(如 JDBC 调用、同步 HTTP 请求)会严重降低吞吐,甚至导致线程饥饿。必须使用反应式客户端(WebClient、R2DBC)。
  • 请求体重复读取:若多次读取请求体(如 readBody 过滤器+鉴权),需注意 DataBuffer 生命周期,否则易导致内存泄漏或请求体丢失。
  • 超时配置不当:网关与下游服务的超时未合理设置,可能导致连接堆积,雪崩效应。需全局配置和按路由配置超时。
  • 版本升级兼容性:Spring Cloud Gateway 版本与 Boot 版本强绑定,大版本升级常有 API 变动,需关注迁移指南。

注意事项

  • 统一异常处理:全局异常处理器应捕获所有异常并返回一致的 JSON 结构,避免因后端错误暴露网关本身细节。
  • 安全头清理:务必剥离内部使用的 Header(如 X-Forwarded-For 需要妥善处理),防止伪造。
  • 限流键选择:使用 RequestRateLimiter 时,Key 的设计(IP、用户、路径)直接决定限流有效性。
  • 禁用默认路由:生产环境不要暴露 Actuator 的 /gateway/routes 无认证访问,安全配置必须严格。
  • 监控与链路追踪:务必接入 Micrometer 和 Sleuth,通过端点监控路由延迟、状态码分布、吞吐量。
  • 优雅关闭:使用 Netty 的优雅停机,确保已接收的请求处理完毕再关闭容器。

替代方案

  1. Kong
  • 基于 OpenResty(Nginx + Lua),高性能,插件丰富,支持多语言,但需要运维 OpenResty 和数据库(PostgreSQL/Cassandra)。适合异构系统、需要独立于 Java 栈的团队。
  1. Apache APISIX
  • 同样是基于 Nginx/OpenResty,纯云原生设计,支持多语言插件,控制面与数据面分离,性能极高,社区活跃。适合大规模、高性能场景。
  1. Traefik
  • Golang 编写,自动化配置,与容器编排(Docker、K8s)原生集成,适合容器化、微服务架构。声明式配置简单,但自定义扩展不如 Java 灵活。
  1. Zuul 2
  • Netflix 自己的反应式网关,与 Spring Cloud 整合不如 Gateway 紧密,逐渐边缘化。
  1. 自建 Nginx + Lua/OpenResty
  • 灵活性最高,能精细控制,但需要团队有较强的 Nginx 和 Lua 能力,开发维护成本高。
  1. 云厂商 API 网关
  • 阿里云、AWS、GCP 等提供的全托管服务,免运维,按量计费,但存在供应商锁定,可定制性较差。

对于 Spring Cloud 微服务体系 的团队,Spring Cloud Gateway 通常是最自然的选择,因为它能最大化利用已有的技能栈和基础设施,降低集成成本。


总结

Spring Cloud Gateway 是 Java 微服务架构下流量入口的优秀实现,它完美契合 Spring 生态,凭借异步非阻塞的特性提供了极高的吞吐能力。它不仅仅是反向代理,而是一个可编程、可扩展的网关框架,能够在不侵入业务代码的前提下,统一处理路由、认证、限流、熔断、灰度等横切关注点。

但它并非银弹。你必须习惯响应式编程思维,避免阻塞操作,谨慎设计过滤器链,并辅以完善的监控和配置管理。对于已有大量基于 Servlet 阻塞式代码的旧系统,过渡期可能需要混合网关方案(如前面再挂一层 Nginx 做路由转发)。

总的来说,当团队拥抱 Spring Cloud 全栈并愿意投入 WebFlux 的学习时,Spring Cloud Gateway 是目前最匹配、最强大的网关方案;如果团队更倾向于语言无关、运维驱动或极高性能需求,则应当考虑 Kong 或 APISIX 等外部网关。