Spring Cloud Gateway 路由

FreeGuideOnline 最新 2026-07-14

Spring Cloud Gateway 路由完全指南

Spring Cloud Gateway 是 Spring 生态中基于 Spring WebFlux 的 API 网关,专为微服务架构设计。路由是其核心功能,它决定了请求如何被转发到下游服务。本教程将从零开始,带你掌握路由配置、谓词断言、过滤器以及动态路由,内容面向初学者,追求高信息密度与实践性。

什么是 Spring Cloud Gateway?

Spring Cloud Gateway 建立在 Spring Boot 2.x 和 Project Reactor 之上,提供了一种简单、有效的方式对 API 进行路由管理。它具备以下核心能力:

  • 路由:将外部请求映射到内部微服务地址
  • 断言:匹配请求的特征(路径、头信息、参数等)
  • 过滤:在请求转发前或响应返回前修改报文

与 Zuul 1.x 相比,Gateway 使用非阻塞 I/O,支持长连接(如 WebSocket),性能更高,功能更现代。

路由基础概念

路由(Route)、断言(Predicate)和过滤器(Filter)是 Gateway 的三大组件,理解它们是掌握路由的前提。

路由(Route)

路由是一个完整的转发规则,由 ID(唯一标识)、目标 URI、一组谓词和一组过滤器组成。当谓词条件全部满足时,请求将被路由到目标 URI。

断言(Predicate)

断言是 Java 8 的 Predicate 接口,输入参数是 Spring Framework 的 ServerWebExchange。Gateway 内置了多种断言工厂,可以让你通过配置灵活定义匹配条件,如路径、请求方法、时间窗口等。

过滤器(Filter)

过滤器用于在请求被转发前后修改报文或执行额外逻辑。Gateway 分为两类过滤器:

  • GatewayFilter:应用于单个路由
  • GlobalFilter:全局作用于所有路由

过滤器可通过实现 GatewayFilterFactory 来自定义。

快速入门:创建第一个路由

让我们从最简示例开始,将一个以 /api/hello 开头的请求转发到本地 http://localhost:8080 的服务。

添加依赖

在 Spring Boot 项目的 pom.xml 中添加 Spring Cloud Gateway 依赖(Spring Cloud 版本需匹配):

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

配置 application.yml

application.yml 中定义路由规则:

spring:
  cloud:
    gateway:
      routes:
        - id: hello_route
          uri: http://localhost:8080
          predicates:
            - Path=/api/hello/**

解释

  • id:路由的唯一标识,建议具有业务含义
  • uri:目标服务地址,支持 httplb(负载均衡)等协议
  • predicates:断言列表,这里匹配所有以 /api/hello 开头的请求路径

编写主类

常规的 Spring Boot 启动类,无需额外注解即可使用 Gateway 功能:

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

启动并测试

启动 Gateway 应用(默认端口 8080),随后访问 http://localhost:8080/api/hello。如果后端 http://localhost:8080 有对应接口,请求将被成功转发。

路由谓词详解

Gateway 内置了十几个谓词工厂,可通过组合它们实现精准匹配。以下是最常用的几种。

After/Before/Between 路由

基于时间的谓词,控制路由在特定时间窗口内生效。

predicates:
  - After=2025-01-01T00:00:00.000+08:00[Asia/Shanghai]   # 在此时间之后生效
  - Before=2025-12-31T23:59:59.000+08:00[Asia/Shanghai]  # 在此时间之前生效
  - Between=2025-06-01T00:00:00.000+08:00[Asia/Shanghai], 2025-06-30T23:59:59.000+08:00[Asia/Shanghai] # 时间段内生效

Cookie/Header/Host 路由

根据 Cookie、Header 或请求主机进行匹配:

predicates:
  - Cookie=chocolate, ch.p  # 含有 cookie chocolate 且值匹配正则 ch.p
  - Header=X-Request-Id, \d+  # 头部 X-Request-Id 存在且为数字
  - Host=**.example.com       # Host 匹配 .example.com 的子域名

Method/Path/Query 路由

最常用的匹配方式:

  • Method:匹配 HTTP 方法,如 GET、POST
  • Path:匹配请求路径,支持 Ant 风格通配符
  • Query:匹配查询参数,可指定参数名和可选的正则值
predicates:
  - Method=GET,POST
  - Path=/user/{segment}   # 路径变量,可用于过滤器
  - Query=version, v\d+    # 包含参数 version 且值匹配 v后面跟数字

权重路由

权重路由可以将流量按比例分发给不同目标,常用于灰度发布或 A/B 测试。它需要配合 Weight 路由谓词工厂,并在 group 下定义多个路由。

spring:
  cloud:
    gateway:
      routes:
        - id: version_v1
          uri: http://localhost:8081
          predicates:
            - Path=/api/**
            - Weight=group1, 80
        - id: version_v2
          uri: http://localhost:8082
          predicates:
            - Path=/api/**
            - Weight=group1, 20

上方配置表示 /api/** 的请求中,80% 流向 v1 服务,20% 流向 v2 服务。同一 group 下所有权重要求和必须为 100。

路由过滤器

过滤器是 Gateway 扩展的核心,内置的过滤器工厂覆盖大多数场景,也支持自定义。

AddRequestHeader 过滤器

在转发请求时添加自定义请求头,适用于向下游传递额外信息。

filters:
  - AddRequestHeader=X-Request-Foo, Bar

AddRequestParameter 过滤器

为下游服务添加请求参数:

filters:
  - AddRequestParameter=flag, enabled

请求将被附加 ?flag=enabled

RewritePath 过滤器

重写请求路径,常用于去除 API 前缀或重新组织路径结构。

filters:
  - RewritePath=/api/(?<segment>.*), /$\{segment}

例如 /api/user/123 转发到下游时变为 /user/123

自定义过滤器

实现自定义逻辑可继承 AbstractGatewayFilterFactory。下例创建一个记录请求耗时的过滤器:

@Component
public class ElapsedGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            long start = System.currentTimeMillis();
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                long elapsed = System.currentTimeMillis() - start;
                System.out.println("Request took " + elapsed + "ms");
            }));
        };
    }
}

在 yaml 中可直接使用 Elapsed 作为过滤器名(ElapsedGatewayFilterFactory 会去掉后缀)。

动态路由——结合注册中心

静态配置路由虽然简单,但微服务动态扩缩容场景下需要服务发现能力。Gateway 集成了多种注册中心,支持通过服务 ID 转发。

集成 Eureka

添加 Eureka 客户端依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

配置启用服务发现,并使用 lb 协议:

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  # 开启从注册中心动态创建路由的功能
          lowerCaseServiceId: true
      routes:
        - id: user_service_route
          uri: lb://user-service   # lb 表示负载均衡,user-service 为注册中心的服务名
          predicates:
            - Path=/user/**

此时 Gateway 会自动从 Eureka 订阅 user-service 的实例列表,实现负载均衡路由。

集成 Nacos

与 Eureka 类似,依赖替换为 spring-cloud-starter-alibaba-nacos-discovery,配置指向 Nacos 地址:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: order_service_route
          uri: lb://order-service
          predicates:
            - Path=/order/**

使用服务 ID 进行路由

开启 spring.cloud.gateway.discovery.locator.enabled=true 后,Gateway 会为每个注册中心的服务自动创建路由,规则为 /{serviceId}/**。例如服务 demo-service 会自动映射路径 /demo-service/**。你也可以继续自定义路由覆盖默认规则。

最佳实践与常见问题

  • 路由顺序:多个路由可能匹配同一个请求,Gateway 按定义顺序依次匹配,第一个满足所有谓词的路由会被执行。注意将精确路由放在前面。
  • 超时配置:通过 spring.cloud.gateway.httpclient.connect-timeoutresponse-timeout 控制连接与响应超时,防止下游故障拖垮网关。
  • 断路由:结合 Resilience4J 或 Sentinel 实现熔断,防止雪崩。
  • 日志与监控:启用 Gateway 访问日志,结合 Actuator 端点查看路由列表、指标等。
  • 避免简单转发:不应将 Gateway 作为透明代理,而应显式定义所有合法入口,关闭未声明的路径访问。

总结

Spring Cloud Gateway 的路由功能为我们提供了强大的 API 入口控制能力。通过声明式配置的谓词与过滤器,可以轻松实现请求匹配、转发、修改、限流与灰度发布。结合注册中心后,更能实现完全动态的服务寻址。掌握这些知识,你已能够在微服务体系中构建稳定、高效的网关层。

现在,你可以尝试添加更多路由谓词,编写自定义过滤器,并与 Eureka/Nacos 集成,让路由能力真正服务于你的业务。