Spring Cloud Gateway 4.3 实战指南:从入门到精通
-
- 一、什么是 Spring Cloud Gateway?
- 二、环境准备与依赖引入
-
- 2.1 版本说明
- 2.2 关键依赖
- 三、网关配置详解
-
- 3.1 4.3 之前的配置方式
- 3.2 4.3 及以后的新配置方式
- 3.3 动态路由:什么是动态路由?
- 3.4 负载均衡:网关如何实现负载均衡?
- 四、路由(Route)的核心组成
- 五、断言(Predicates)全面解析
-
- 5.1 什么是断言?
- 5.2 常用断言工厂
-
- 5.2.1 Path 断言 – 路径匹配
- 5.2.2 Method 断言 – HTTP 方法匹配
- 5.2.3 Header 断言 – 请求头匹配
- 5.2.4 Query 断言 – 查询参数匹配
- 5.2.5 Cookie 断言 – Cookie 匹配
- 5.2.6 时间相关断言
- 5.2.7 Host 断言 – Host 头匹配
- 5.2.8 RemoteAddr 断言 – 客户端 IP 匹配
- 5.3 断言与自动路由的关系
- 六、过滤器(Filters)的使用
-
- 6.1 什么是过滤器?
- 6.2 路由过滤器(filters)
- 6.3 默认过滤器(default-filters)
- 6.4 自定义全局过滤器
- 6.5 过滤器执行顺序
- 七、与 Nacos 集成的最佳实践
-
- 7.1 配置一致性
- 7.2 负载均衡器强制要求
- 7.3 路由过滤器与 Feign 拦截器的协作
- 八、总结
一、什么是 Spring Cloud Gateway?
在微服务架构中,一个系统会被拆分成多个独立的服务(如用户服务、订单服务、商品服务)。如果没有网关,客户端需要直接调用多个微服务,这会带来:
- 客户端复杂:需要维护所有服务的地址,处理服务发现、负载均衡、重试等逻辑。
- 横切关注点难以统一:认证、授权、日志、监控等功能需要在每个服务中重复实现。
- 安全性差:内部服务直接暴露,容易受到攻击。
API 网关作为系统的统一入口,位于客户端和后端服务之间,所有外部请求首先到达网关,然后由网关根据配置的路由规则转发到具体的微服务。网关集中处理横切关注点,如身份认证、限流、日志、监控等,大大简化了客户端和服务端的复杂度。
Spring Cloud Gateway 是 Spring Cloud 生态中基于 Spring WebFlux 构建的 API 网关,旨在提供一种简单、有效的方式来路由到 API,并为它们提供横切关注点。它具有以下特点:
- 基于 WebFlux 和 Project Reactor:非阻塞、响应式编程模型,性能优异,适合高并发场景。
- 两种实现栈:从 4.x 版本开始,同时支持 WebFlux(响应式)和 Web MVC(传统 Servlet)两种实现方式,开发者可根据项目需求选择。
- 强大的路由功能:通过断言(Predicates)和过滤器(Filters)灵活定义路由规则。
- 与服务发现无缝集成:可配合 Nacos、Eureka 等注册中心实现动态路由。
- 内置负载均衡:与 Spring Cloud LoadBalancer 集成,支持多种负载均衡策略。
本文将基于实际项目经验,详细讲解 Spring Cloud Gateway 4.3 的核心概念、配置方法及最佳实践。
二、环境准备与依赖引入
2.1 版本说明
- Spring Cloud 版本:2025.0.1(即 Gateway 4.3)
- Spring Boot 版本:3.5.x(与 Cloud 2025.0.x 兼容)
2.2 关键依赖
在 4.3 版本中,Gateway 对 Starter 进行了重命名,以区分 WebFlux 和 MVC 两种实现栈:
- 旧 Starter(仍可用但已过时):spring-cloud-starter-gateway
- 新 Starter(推荐):spring-cloud-starter-gateway-server-webflux
若需集成 Nacos 作为注册中心,需同时添加以下依赖:
<!– Nacos 服务发现 –>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!– 负载均衡器(Gateway 4.3 强制要求) –>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!– Gateway 核心 –>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway-server-webflux</artifactId>
</dependency>
注意:Gateway 4.3 已彻底移除 Ribbon,必须手动引入 spring-cloud-starter-loadbalancer,否则无法解析 lb:// 协议。
三、网关配置详解
在深入配置之前,我们需要先理解网关配置的两种风格。在 4.3 版本中,官方引入了更具层级的配置结构,明确区分 WebFlux 和 MVC 栈。
3.1 4.3 之前的配置方式
在 4.3 之前的版本,配置通常直接位于 spring.cloud.gateway 下:
spring:
cloud:
gateway:
discovery:
locator:
enabled: true # 启用服务发现自动路由
routes:
– id: user
uri: lb://lqb–user
predicates:
– Path=/api/user/**
– id: bank
uri: lb://lqb–bank
predicates:
– Path=/api/bank/**
3.2 4.3 及以后的新配置方式
从 Spring Cloud Gateway 4.x(对应 Cloud 2023.0+)开始,官方推荐使用更具层级的配置,对于 WebFlux 实现,配置需置于 spring.gateway.server.webflux 下:
spring:
gateway:
server:
webflux:
discovery:
locator:
enabled: true # 启动服务发现自动路由
routes:
– id: user
uri: lb://lqb–user
predicates:
– Path=/api/user/**
– id: bank
uri: lb://lqb–bank
predicates:
– Path=/api/bank/**
注意:这种新写法使配置意图更清晰,但两种方式目前均被支持。若同时使用,新版配置优先级更高。
3.3 动态路由:什么是动态路由?
动态路由是指网关能够根据服务注册中心(如 Nacos)中的服务列表,自动为每个服务生成路由规则,无需手动配置每个服务的地址。当 discovery.locator.enabled=true 时,Gateway 会自动创建形如 /${serviceId}/** 的路由,转发到 lb://${serviceId}。这样,新服务上线后即可通过网关访问,大大提高了系统的可维护性。
例如,服务 lqb-bank 会自动生成路由匹配 /lqb-bank/**。如果手动定义了路由(如 /api/bank/**),且与自动路由存在重叠,手动定义的路由优先级更高,会覆盖自动路由的行为。
3.4 负载均衡:网关如何实现负载均衡?
负载均衡是网关的核心能力之一,它负责将请求分发到服务的多个实例。Spring Cloud Gateway 通过 lb:// 前缀与 Spring Cloud LoadBalancer 集成,实现客户端负载均衡。在 Gateway 4.3 中,Ribbon 已被彻底移除,必须显式引入 spring-cloud-starter-loadbalancer。结合 Nacos,还可以实现权重、同集群优先等高级策略(详见第七节)。
四、路由(Route)的核心组成
在开始编写路由配置前,必须理解什么是路由。路由是网关最基本的组成单元,它定义了当请求满足什么条件时,应该被转发到哪里。一个完整的路由由以下四部分组成:
- id:路由的唯一标识,建议使用有业务含义的名称。
- predicates:断言(条件)数组,决定是否匹配该路由。
- filters:过滤器数组(可选),在请求转发前后修改请求或响应。
- uri:目标地址,支持普通 HTTP 地址(如 http://example.com)或注册中心服务名(如 lb://lqb-bank,lb 表示启用负载均衡)。
以下是一个包含过滤器的路由配置示例:
spring:
gateway:
server:
webflux:
routes:
– id: user
uri: lb://lqb–user
predicates:
– Path=/api/user/**
filters:
– AddRequestHeader=X–Request–red, blue # 添加请求头
五、断言(Predicates)全面解析
5.1 什么是断言?
**断言(Predicate)是路由匹配的“裁判员”,它决定了请求是否符合当前路由的条件。Gateway 内置了多种断言工厂,可以基于请求的路径、方法、头信息、参数、时间、Cookie、Host、IP 等进行匹配。多个断言之间是逻辑与(AND)**关系,必须全部满足才会触发路由。
例如,以下断言要求请求路径以 /api/user 开头且为 GET 方法:
predicates:
– Path=/api/user/**
– Method=GET
5.2 常用断言工厂
5.2.1 Path 断言 – 路径匹配
predicates:
– Path=/user/**, /api/order/** # 匹配 /user 或 /api/order 开头的任意路径
支持 Ant 风格通配符:* 匹配单级路径,** 匹配多级路径。
5.2.2 Method 断言 – HTTP 方法匹配
predicates:
– Method=GET, POST # 仅匹配 GET 和 POST 请求
5.2.3 Header 断言 – 请求头匹配
predicates:
– Header=X–Request–Id, \\d+ # 要求头 X-Request-Id 存在且值为数字
第一个参数是头名,第二个是可选的正则表达式。
5.2.4 Query 断言 – 查询参数匹配
predicates:
– Query=foo, bar. # 要求参数 foo 存在且值匹配正则 bar.
– Query=baz # 只要求存在参数 baz,不校验值
5.2.5 Cookie 断言 – Cookie 匹配
predicates:
– Cookie=sessionId, 12345 # 要求 Cookie 中存在 sessionId=12345
5.2.6 时间相关断言
- After:在指定时间之后
- Before:在指定时间之前
- Between:在两个时间之间
predicates:
– After=2026–03–08T10:00:00+08:00[Asia/Shanghai]
– Before=2026–12–31T23:59:59+08:00
– Between=2026–03–01T00:00:00+08:00, 2026-03-31T23:59:59+08:00
5.2.7 Host 断言 – Host 头匹配
predicates:
– Host=**.example.com, *.test.org # 匹配 example.com 的子域或 test.org
5.2.8 RemoteAddr 断言 – 客户端 IP 匹配
predicates:
– RemoteAddr=192.168.1.1/24 # 匹配 192.168.1.0/24 网段
5.3 断言与自动路由的关系
当启用服务发现自动路由时,每个服务会有一个默认断言 Path=/${serviceId}/**。手动定义的断言会覆盖或补充自动路由的断言。可通过开启 DEBUG 日志观察实际生效的路由:
logging:
level:
org.springframework.cloud.gateway: DEBUG
六、过滤器(Filters)的使用
6.1 什么是过滤器?
**过滤器(Filter)**是路由的“加工厂”,它可以在请求被转发到下游服务之前或之后,对请求或响应进行修改。过滤器分为三种类型:
- 路由过滤器(GatewayFilter):仅对特定路由生效,配置在 routes.filters 下。
- 默认过滤器(Default Filters):对所有路由生效,配置在 default-filters 下。
- 全局过滤器(GlobalFilter):作用于所有路由,但需要编写代码实现,通常用于实现横切关注点,如鉴权、日志等。
过滤器可以用于添加/修改请求头、添加请求参数、重写路径、限流、重试等。多个过滤器会按照顺序执行,它们的执行优先级由 Ordered 接口或声明顺序决定。
6.2 路由过滤器(filters)
在特定路由下配置,仅对当前路由生效:
spring:
gateway:
server:
webflux:
routes:
– id: user
uri: lb://lqb–user
predicates:
– Path=/api/user/**
filters:
– AddRequestHeader=X–Request–red, blue # 添加请求头
6.3 默认过滤器(default-filters)
对所有路由生效,配置在与 routes 平级的 default-filters 下:
spring:
gateway:
server:
webflux:
default-filters:
– AddRequestParameter=color, blue # 为所有请求添加查询参数
6.4 自定义全局过滤器
通过实现 GlobalFilter 和 Ordered 接口,可以编写自定义全局过滤器。例如,实现一个简单的鉴权过滤器,检查请求头是否包含 Authorization:
@Component
public class AuthorizationFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 检查请求头是否包含 Authorization
if (!exchange.getRequest().getHeaders().containsKey("Authorization")) {
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete(); // 拦截
}
return chain.filter(exchange); // 放行
}
@Override
public int getOrder() {
return 0; // 优先级,数字越小越靠前执行
}
}
6.5 过滤器执行顺序
当多个过滤器同时存在时,它们的执行顺序遵循以下规则:
- 如果过滤器实现了 Ordered 接口,则按 getOrder() 返回值排序,值越小优先级越高。
- 路由过滤器和默认过滤器会按声明顺序分配 order 值(从 0 开始递增)。
- 若 order 值相同,则执行顺序为:全局过滤器 > 默认过滤器 > 路由过滤器。
七、与 Nacos 集成的最佳实践
7.1 配置一致性
确保网关的命名空间和分组与微服务保持一致,否则无法发现服务。这里涉及服务发现组件集成的概念:Gateway 需要与注册中心通信以获取服务实例列表,因此必须配置正确的命名空间和分组。
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: d0247d5f–d454–47cd–ad12–e59c70bd207c
group: DEV–01
7.2 负载均衡器强制要求
Gateway 4.3 完全移除了 Ribbon,必须引入 spring-cloud-starter-loadbalancer,否则 lb:// 协议无法解析。同时,若需利用 Nacos 的权重或同集群优先访问,可开启 Nacos 负载均衡扩展:
spring:
cloud:
loadbalancer:
nacos:
enabled: true
7.3 路由过滤器与 Feign 拦截器的协作
网关添加的请求头(如 AddRequestHeader)仅作用于网关转发到微服务的请求。若微服务内部通过 Feign 调用其他服务,需通过 Feign 拦截器将请求头传递下去。例如:
filters:
– AddRequestHeader=X–Gateway–Token, test–token # 网关添加自定义头
然后在 Feign 拦截器中复制该头(如需要)。
八、总结
Spring Cloud Gateway 作为微服务架构的“门面”,通过路由、断言、过滤器等核心概念,提供了强大而灵活的请求处理能力。本文从基础概念入手,详细讲解了 Gateway 4.3 的配置方法、断言工厂、过滤器体系以及与 Nacos 的集成实践。掌握这些知识后,你将能够构建一个高效、可扩展的 API 网关,统一处理认证、限流、日志等横切关注点,让微服务系统更加健壮和易于维护。
参考链接:
- Spring Cloud Gateway 官方文档
- Spring Cloud Alibaba 文档
