Spring Cloud Gateway用法

3 阅读18分钟

Spring Cloud Gateway 是 Spring Cloud 生态中的官方API网关组件,用于替代已停更的 Spring Cloud Zuul,基于 Spring WebFlux 构建(响应式编程),核心定位是“微服务请求的统一入口”,负责路由转发、限流、身份认证、日志监控等核心功能,是微服务架构中不可或缺的核心组件。

本文延续此前 Sentinel、Seata 文档的逻辑结构,分为「核心知识点、实战用法、高频面试题」三大模块,既覆盖基础理论,又提供可直接落地的实战步骤,同时整理企业高频面试题及标准答案,适配开发、学习与面试多重需求,确保上下文流畅、重点突出、实用性强。

一、Spring Cloud Gateway 核心知识点(必懂基础)

1. 核心定位与设计理念

① 核心定位:微服务统一入口与流量管控中心,所有客户端请求(Web、APP、第三方服务)均通过 Gateway 进入微服务集群,实现对微服务的统一管控,隔离客户端与微服务,降低客户端与服务端的耦合。

② 设计理念:基于“响应式编程”(Spring WebFlux),采用“过滤器链”模式,将请求处理拆分为多个可配置的过滤器,实现路由转发、限流、认证等功能的解耦,支持动态配置,适配高并发微服务场景。

③ 核心优势(对比 Zuul):

  • 性能更优:基于 Netty + Spring WebFlux 实现非阻塞 IO,响应式编程模型,吞吐量远高于 Zuul(基于 Servlet 阻塞模型);
  • 功能更丰富:原生支持路由转发、限流、熔断、身份认证、请求过滤等功能,无需额外集成第三方组件;
  • 生态更适配:无缝集成 Spring Cloud 核心组件(Nacos、Sentinel、OpenFeign 等),支持动态路由配置;
  • 官方维护:Spring 官方出品,持续更新迭代,替代停更的 Zuul,是微服务网关的首选。

2. 核心概念(重中之重)

Spring Cloud Gateway 的所有功能都围绕“路由、断言、过滤器”三大核心概念展开,理解这三个概念,就能掌握 Gateway 的核心工作机制:

(1)路由(Route)—— 核心组件

定义:Gateway 最基本的组件,代表“一个请求转发规则”,由「ID、断言、过滤器、目标URI」四部分组成,是请求转发的核心配置。

  • ID:路由的唯一标识,不可重复(如 route-order、route-stock);
  • 断言(Predicate):用于匹配客户端请求的条件(如请求路径、请求方法、请求参数),只有满足断言条件的请求,才会被转发到目标URI;
  • 过滤器(Filter):用于对请求/响应进行拦截和处理(如添加请求头、修改响应内容、限流、认证);
  • 目标URI:请求最终被转发到的微服务地址(如 http://service-order、lb://service-stock,lb 表示负载均衡)。

核心逻辑:客户端请求 → Gateway → 匹配路由断言 → 执行过滤器链 → 转发到目标微服务 → 执行响应过滤器 → 返回结果给客户端。

(2)断言(Predicate)—— 路由匹配规则

定义:本质是“请求匹配条件”,Gateway 内置了多种常用断言,也支持自定义断言,用于判断请求是否符合当前路由的转发规则。

常用内置断言(必记):

  • Path 断言:根据请求路径匹配(最常用),如 Path=/order/** 表示匹配所有以 /order 开头的请求;
  • Method 断言:根据请求方法匹配,如 Method=GET,POST 表示只匹配 GET、POST 请求;
  • Query 断言:根据请求参数匹配,如 Query=token 表示请求必须包含 token 参数;
  • Header 断言:根据请求头匹配,如 Header=Authorization 表示请求必须包含 Authorization 请求头;
  • Host 断言:根据请求主机地址匹配,如 Host=*.example.com 表示匹配所有 example.com 后缀的主机请求;
  • After 断言:根据请求时间匹配,如 After=2026-01-01T00:00:00+08:00[Asia/Shanghai] 表示只匹配该时间之后的请求。

补充:多个断言可以组合使用,只有所有断言都满足,请求才会被转发。

(3)过滤器(Filter)—— 请求/响应处理

定义:用于拦截和处理请求/响应,实现请求过滤、修改、限流、认证等功能,分为「全局过滤器」和「局部过滤器」两类,二者协同工作。

① 局部过滤器(Route Filter)

作用范围:仅作用于指定的路由,需要在路由配置中单独指定,Gateway 内置了多种局部过滤器(如添加请求头、重写路径)。

常用局部过滤器:

  • AddRequestHeader:给请求添加指定请求头;
  • AddResponseHeader:给响应添加指定响应头;
  • RewritePath:重写请求路径(如将 /api/order 重写为 /order);
  • StripPrefix:去除请求路径的前缀(如 StripPrefix=1 表示去除路径的第一个层级)。
② 全局过滤器(Global Filter)

作用范围:作用于所有路由,无需在路由中配置,自动生效,常用于全局认证、全局限流、全局日志等场景(如 Token 校验、请求日志记录)。

常用全局过滤器:

  • LoadBalancerClientFilter:实现负载均衡(自动将 lb://service-name 转换为具体的微服务地址);
  • NettyRoutingFilter:负责将请求转发到目标微服务;
  • 自定义全局过滤器:实现 GlobalFilter 接口,自定义业务逻辑(如 Token 认证、权限校验)。

3. 核心架构与工作流程

(1)架构组成

Spring Cloud Gateway 基于 Spring WebFlux 构建,核心由「路由解析器、断言处理器、过滤器链、请求转发器」四部分组成,依赖 Netty 服务器实现非阻塞 IO,支持高并发。

(2)核心工作流程(5步,必懂)

  1. 客户端发送请求到 Spring Cloud Gateway;
  2. Gateway 接收请求,通过路由解析器解析所有已配置的路由;
  3. 通过断言处理器,匹配当前请求对应的路由(满足所有断言条件);
  4. 执行该路由的局部过滤器 + 全局过滤器(形成过滤器链,按顺序执行);
  5. 通过请求转发器,将请求转发到目标微服务,接收微服务的响应后,执行响应过滤器,最终将响应返回给客户端。

4. 关键特性(面试常考)

  • 响应式编程:基于 Spring WebFlux,非阻塞 IO,适配高并发场景,吞吐量高;
  • 动态路由:支持通过配置中心(Nacos/Apollo)动态配置路由,无需重启 Gateway;
  • 负载均衡:内置负载均衡功能,支持 lb:// 协议,自动将请求分发到微服务集群;
  • 熔断限流:无缝集成 Sentinel、Resilience4j,实现路由级别的限流、熔断;
  • 可扩展性:支持自定义断言、自定义过滤器,适配复杂业务场景;
  • 集成性强:无缝集成 Spring Cloud 生态组件(Nacos、OpenFeign、Sleuth 等)。

二、Spring Cloud Gateway 实战用法(重点,可直接落地)

实战核心是“搭建 Gateway 服务→配置路由→配置过滤器→集成核心组件(Nacos、Sentinel)→测试验证”,以下基于 Spring Cloud Alibaba + Gateway + Nacos 生态,讲解最常用的实战步骤,适配企业开发场景(全程可复制)。

1. 第一步:搭建 Gateway 基础服务

(1)创建 Spring Boot 项目,引入依赖

在 pom.xml 中引入 Gateway 核心依赖、Nacos 注册发现依赖(Gateway 需注册到 Nacos,以便发现微服务):

<!-- Spring Cloud Gateway 核心依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Spring Cloud Alibaba Nacos 注册发现依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 可选:集成 Sentinel 实现限流(后续实战会用到) -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

注意:Gateway 依赖 Spring WebFlux,不能引入 spring-boot-starter-web 依赖(会导致冲突,启动失败)。

(2)配置 application.yml(基础配置)

配置 Gateway 端口、Nacos 注册地址,以及基础路由规则(以转发到订单服务、库存服务为例):

server:
  port: 8080  # Gateway 端口(客户端统一入口端口)

spring:
  application:
    name: gateway-service  # Gateway 服务名
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848  # Nacos 注册中心地址(需提前启动Nacos)
    gateway:
      # 开启基于 Nacos 的动态路由(可选,后续进阶会用到)
      discovery:
        locator:
          enabled: true  # 开启服务发现,可通过 http://localhost:8080/服务名/接口路径 访问微服务
      # 静态路由配置(基础用法)
      routes:
        # 路由1:转发到订单服务(service-order)
        - id: route-order  # 路由唯一ID
          uri: lb://service-order  # 目标微服务地址(lb表示负载均衡,service-order是订单服务在Nacos的服务名)
          predicates:  # 断言(匹配请求条件)
            - Path=/order/**  # 匹配所有以 /order 开头的请求
          filters:  # 局部过滤器
            - StripPrefix=1  # 去除请求路径的第一个前缀(如 /order/getById → /getById)
            - AddResponseHeader=X-Response-From, Gateway  # 给响应添加请求头
        # 路由2:转发到库存服务(service-stock)
        - id: route-stock
          uri: lb://service-stock
          predicates:
            - Path=/stock/**
            - Method=GET,POST  # 只匹配GET、POST请求
          filters:
            - StripPrefix=1

(3)启动 Gateway 服务

创建启动类(无需额外注解,Spring Boot 自动识别 Gateway):

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient  // 开启服务注册发现(Nacos)
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

启动成功后,可在 Nacos 控制台的“服务列表”中看到 gateway-service 服务(注册成功)。

2. 第二步:测试基础路由转发

前提:启动 Nacos、Gateway 服务、订单服务(service-order)、库存服务(service-stock),订单服务提供 /getById 接口,库存服务提供 /deduct 接口。

测试请求(通过 Gateway 转发):

3. 第三步:配置过滤器(局部+全局)

(1)局部过滤器(已在基础配置中演示)

常用局部过滤器补充配置(在 routes.filters 中添加):

filters:
  - RewritePath=/api/order/(?<segment>.*), /order/${segment}  # 重写路径:/api/order/getById → /order/getById
  - AddRequestHeader=Token, 123456789  # 给请求添加 Token 请求头
  - SetResponseHeader=Content-Type, application/json;charset=utf-8  # 设置响应头

(2)自定义全局过滤器(实战常用,如 Token 认证)

实现 GlobalFilter 接口,自定义全局过滤器,用于所有路由的 Token 校验(未携带 Token 则拒绝请求):

import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Configuration
public class CustomGlobalFilterConfig {

    // 自定义全局过滤器(Token 认证),Order 越小,执行顺序越靠前
    @Bean
    @Order(-1)  // 优先执行 Token 校验
    public GlobalFilter tokenAuthFilter() {
        return (exchange, chain) -> {
            // 1. 获取请求头中的 Token
            String token = exchange.getRequest().getHeaders().getFirst("Token");
            // 2. 校验 Token(实际场景中,从 Redis 或配置中心获取合法 Token)
            if (token == null || token.isEmpty() || !"123456789".equals(token)) {
                // 3. Token 无效,返回 401 未授权
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
            // 4. Token 有效,继续执行过滤器链,转发请求
            return chain.filter(exchange);
        };
    }

    // 自定义全局过滤器(请求日志记录)
    @Bean
    @Order(0)
    public GlobalFilter logFilter() {
        return (exchange, chain) -> {
            // 记录请求信息
            String path = exchange.getRequest().getPath().value();
            String method = exchange.getRequest().getMethod().toString();
            System.out.println("Gateway 接收请求:" + method + " " + path);
            // 继续执行过滤器链
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // 记录响应信息
                HttpStatus status = exchange.getResponse().getStatusCode();
                System.out.println("Gateway 响应请求:" + status);
            }));
        };
    }
}

测试:发送请求时未携带 Token 或 Token 错误,Gateway 直接返回 401 未授权;携带正确 Token,正常转发请求。

4. 第四步:集成 Nacos 实现动态路由(企业级必备)

静态路由配置(application.yml 中配置)的缺点是:修改路由后需重启 Gateway,企业级开发中需实现动态路由(修改配置无需重启),常用方案是基于 Nacos 配置中心实现。

(1)引入 Nacos 配置中心依赖

<!-- Spring Cloud Alibaba Nacos 配置中心依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

(2)创建 bootstrap.yml 配置文件

配置 Nacos 配置中心地址,指定配置文件名称(用于存储动态路由):

spring:
  cloud:
    nacos:
      config:
        server-addr: localhost:8848  # Nacos 配置中心地址
        file-extension: yaml  # 配置文件格式
        group: DEFAULT_GROUP  # 配置分组
        name: gateway-config  # 配置文件名称(Nacos 中创建该配置)
  application:
    name: gateway-service

(3)在 Nacos 中创建动态路由配置

  1. 登录 Nacos 控制台,进入“配置管理→配置列表”,点击“新增配置”;

  2. 配置信息:

    1. Data ID:gateway-config.yaml(与 bootstrap.yml 中 name + file-extension 一致);
    2. Group:DEFAULT_GROUP;
    3. 配置格式:YAML;
    4. 配置内容(动态路由规则,与 application.yml 中 routes 配置一致): spring: `` cloud: `` gateway: `` routes: `` - id: route-order `` uri: lb://service-order `` predicates: `` - Path=/order/** `` filters: `` - StripPrefix=1 `` - id: route-stock `` uri: lb://service-stock `` predicates: `` - Path=/stock/** `` - Method=GET,POST `` filters: ``- StripPrefix=1
  3. 点击“发布”,配置生效。

(4)测试动态路由

修改 Nacos 中的路由配置(如新增一个路由、修改断言条件),无需重启 Gateway,等待 1-3 秒(默认刷新间隔),配置自动生效,实现动态路由。

5. 第五步:集成 Sentinel 实现路由限流(实战重点)

Gateway 无缝集成 Sentinel,可实现路由级别的限流(如限制 /order 路由的 QPS 为 10),避免单个路由流量过载,保护微服务。

(1)引入 Sentinel 依赖(已在第一步引入)

(2)配置 Sentinel 控制台地址(application.yml 中添加)

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8858  # Sentinel 控制台地址(需提前启动)
        port: 8719
      eager: true  # 立即初始化 Sentinel

(3)在 Sentinel 控制台配置路由限流规则

  1. 启动 Gateway 服务和 Sentinel 控制台,访问 Gateway 接口(触发 Sentinel 初始化);

  2. 登录 Sentinel 控制台,进入“网关流控”,点击“新增网关流控规则”;

  3. 配置规则:

    1. 资源名称:路由 ID(如 route-order);
    2. 限流方式:选择“QPS”或“并发数”;
    3. 阈值:设置具体数值(如 QPS=10,即每秒最多10次请求);
    4. 其他配置:默认即可,点击“确定”。

(4)测试限流

快速请求 http://localhost:8080/order/getById?id=1,当请求超过 QPS 阈值时,Sentinel 触发限流,返回默认限流提示(可自定义限流响应)。

三、Spring Cloud Gateway 高频面试题(含标准答案)

整理企业面试中最常考的 12 道题,涵盖基础、原理、实战、对比,标准答案直击得分点,适配面试作答节奏,无需额外扩充。

1. 什么是 Spring Cloud Gateway?它的核心作用是什么?

标准答案:

Spring Cloud Gateway 是 Spring Cloud 官方推出的 API 网关组件,基于 Spring WebFlux 构建(响应式编程),替代已停更的 Zuul,核心作用是作为微服务的统一入口,实现:

  • 路由转发:将客户端请求根据规则转发到对应微服务;
  • 流量管控:限流、熔断,保护微服务,避免过载;
  • 身份认证:统一校验 Token、权限,避免每个服务单独实现;
  • 请求过滤:修改请求/响应头、重写路径、日志监控;
  • 负载均衡:内置负载均衡,分发请求到微服务集群。

2. Spring Cloud Gateway 的核心组件有哪些?各自的作用是什么?

标准答案:

核心组件有 3 个,缺一不可:

  • 路由(Route):请求转发的规则,由 ID、断言、过滤器、目标 URI 组成,是 Gateway 的核心;
  • 断言(Predicate):请求匹配条件,只有满足断言的请求,才会被转发到目标 URI;
  • 过滤器(Filter):拦截和处理请求/响应,分为局部过滤器(作用于指定路由)和全局过滤器(作用于所有路由),实现认证、限流等功能。

3. Spring Cloud Gateway 的工作流程是什么?

标准答案:

  1. 客户端发送请求到 Spring Cloud Gateway;
  2. Gateway 解析所有已配置的路由,通过断言匹配当前请求对应的路由;
  3. 执行该路由的局部过滤器 + 全局过滤器(按顺序执行过滤器链);
  4. 将请求转发到目标微服务,接收微服务的响应;
  5. 执行响应过滤器,将响应返回给客户端。

4. Spring Cloud Gateway 与 Zuul 的区别?为什么选择 Gateway?

标准答案:

核心区别集中在性能、架构、维护性,选择 Gateway 的核心原因是性能更优、官方维护、功能更丰富:

对比维度Spring Cloud GatewayZuul
底层架构基于 Spring WebFlux + Netty,非阻塞 IO基于 Servlet,阻塞 IO
性能高吞吐量,适配高并发场景性能较差,吞吐量低
维护状态Spring 官方维护,持续更新Netflix 停更,无后续迭代
功能原生支持路由、限流、熔断、动态路由需额外集成第三方组件实现限流、熔断
集成性无缝集成 Spring Cloud 生态(Nacos、Sentinel)集成性较差,适配性不足

5. 什么是动态路由?Spring Cloud Gateway 如何实现动态路由?

标准答案:

① 动态路由:无需重启 Gateway 服务,即可修改路由配置(新增、修改、删除路由),适配企业级场景中频繁调整路由的需求。

② 实现方案(常用):基于配置中心实现,主流是 Nacos/Apollo,核心步骤:

  • Gateway 集成 Nacos 配置中心依赖;
  • 在 Nacos 中创建路由配置文件(存储路由规则);
  • Gateway 从 Nacos 拉取路由配置,配置更新后自动刷新,实现动态路由。

6. Spring Cloud Gateway 的过滤器分为哪两类?区别是什么?

标准答案:

分为「局部过滤器」和「全局过滤器」,核心区别是作用范围不同:

  • 局部过滤器(Route Filter):

    • 作用范围:仅作用于指定的路由,需在路由配置中单独指定;
    • 用途:针对单个路由的个性化处理(如给某个路由添加请求头);
    • 示例:StripPrefix、AddRequestHeader。
  • 全局过滤器(Global Filter):

    • 作用范围:作用于所有路由,无需在路由中配置,自动生效;
    • 用途:全局统一处理(如全局 Token 认证、全局日志);
    • 示例:自定义 Token 校验过滤器、LoadBalancerClientFilter。

7. 如何自定义 Spring Cloud Gateway 的全局过滤器?

标准答案:

核心是实现 GlobalFilter 接口,配合 @Bean 注解注入 Spring 容器,步骤如下:

  1. 创建配置类,实现 GlobalFilter 接口,重写 filter 方法(处理请求/响应);
  2. 通过 @Order 注解指定过滤器执行顺序(Order 越小,执行越靠前);
  3. 通过 @Bean 注解将过滤器注入容器,自动生效(作用于所有路由)。

示例:自定义 Token 认证过滤器,校验请求头中的 Token,无效则返回 401 未授权。

8. Spring Cloud Gateway 如何实现限流?常用的限流方案有哪些?

标准答案:

① 核心实现:Gateway 本身不提供限流功能,需集成第三方组件,最常用的是 Sentinel,其次是 Resilience4j。

② 集成 Sentinel 实现限流的步骤:

  • 引入 spring-cloud-alibaba-sentinel-gateway 依赖;
  • 配置 Sentinel 控制台地址,让 Gateway 与控制台建立连接;
  • 在 Sentinel 控制台配置“网关流控规则”(指定路由 ID、限流阈值);
  • 测试限流:当请求超过阈值时,Sentinel 自动拦截请求,返回限流提示。

③ 常用限流维度:QPS 限流、并发数限流、路由级限流、IP 级限流。

9. Spring Cloud Gateway 中的断言(Predicate)有什么作用?常用的断言有哪些?

标准答案:

① 作用:用于匹配客户端请求的条件,只有满足所有断言条件的请求,才会被转发到目标微服务,实现路由的精准匹配。

② 常用断言:

  • Path:根据请求路径匹配(最常用,如 Path=/order/**);
  • Method:根据请求方法匹配(如 Method=GET,POST);
  • Query:根据请求参数匹配(如 Query=token);
  • Header:根据请求头匹配(如 Header=Authorization);
  • After:根据请求时间匹配(如 After=指定时间)。

10. Spring Cloud Gateway 如何实现负载均衡?

标准答案:

Gateway 内置负载均衡功能,无需额外集成组件,核心依赖 Spring Cloud LoadBalancer,实现步骤:

  1. Gateway 集成 Nacos 注册发现依赖(自动集成 LoadBalancer);
  2. 路由配置中,uri 采用 lb:// 协议(lb 表示负载均衡),后跟微服务在 Nacos 的服务名(如 lb://service-order);
  3. 当微服务集群部署时,Gateway 会自动从 Nacos 获取微服务的所有实例地址,采用默认的轮询策略,将请求分发到不同实例,实现负载均衡。

11. Spring Cloud Gateway 为什么不能引入 spring-boot-starter-web 依赖?

标准答案:

因为 Spring Cloud Gateway 基于 Spring WebFlux 构建,而 spring-boot-starter-web 依赖基于 Servlet 构建,二者底层架构冲突(WebFlux 是非阻塞 IO,Servlet 是阻塞 IO),同时引入会导致 Gateway 启动失败。

补充:Spring WebFlux 是 Spring 推出的响应式编程框架,依赖 Netty 服务器,与 Servlet 容器(如 Tomcat)不兼容。

12. 如何解决 Spring Cloud Gateway 的跨域问题?

标准答案:

跨域问题是客户端(如前端)访问 Gateway 时,因浏览器同源策略导致的请求失败,解决方案是在 Gateway 中配置跨域允许规则,核心配置如下:

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':  # 匹配所有请求路径
            allowed-origins: "*"  # 允许所有来源(生产环境建议指定具体域名)
            allowed-methods: "*"  # 允许所有请求方法
            allowed-headers: "*"  # 允许所有请求头
            allow-credentials: true  # 允许携带cookie
            max-age: 3600  # 跨域请求缓存时间(秒)

四、总结

Spring Cloud Gateway 作为微服务架构的“统一入口”,核心价值是实现请求的统一管控、流量防护和服务隔离,本文延续此前文档的逻辑,全面覆盖「核心知识点、实战用法、高频面试题」,重点突出实战落地步骤(可直接复制使用)和面试得分点。

核心要点:掌握 Gateway 的三大核心组件(路由、断言、过滤器)、工作流程,能独立完成 Gateway 搭建、路由配置、过滤器开发,以及 Nacos 动态路由、Sentinel 限流的集成,同时掌握高频面试题的标准答案,即可应对企业开发和面试的双重需求。