Spring Cloud Gateway 的内置路由过滤器使用

Spring Cloud Gateway 的内置路由过滤器(Built-in Route Filters)是网关核心功能之一,用于对请求 / 响应进行拦截和处理(如修改请求头、添加响应头、路径重写、限流等),无需自定义代码即可满足大部分常见场景。

内置过滤器分为两类:

  • GatewayFilter:单路由生效(仅对配置的路由起作用)。
  • GlobalFilter:全局生效(对所有路由起作用,如负载均衡、熔断等,部分内置全局过滤器默认启用)。

本文重点讲解 单路由级内置 GatewayFilter 的使用,按场景分类说明配置方式(基于 YAML 配置,properties 类似)。

一、核心配置格式

内置过滤器通过 routes.filters 配置,格式为:

yaml

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: 路由ID(唯一)
          uri: 目标服务地址(如 lb://服务名、http://ip:端口)
          predicates: # 路由匹配条件(如路径、方法)
            - Path=/api/**
          filters: # 内置过滤器配置(数组形式,顺序即执行顺序)
            - 过滤器名=参数1,参数2,... # 有参数的过滤器
            - 过滤器名 # 无参数的过滤器

二、常用内置过滤器分类详解

1. 请求头 / 响应头操作

用于添加、修改、移除请求头或响应头,常见场景:传递身份信息、跨域配置、隐藏敏感响应头。

过滤器名 作用 参数格式 示例
AddRequestHeader 给请求添加头 AddRequestHeader = 头名,头值 - AddRequestHeader=X-Request-Source,gateway
AddResponseHeader 给响应添加头 AddResponseHeader = 头名,头值 - AddResponseHeader=X-Response-Time,${currentTime}
RemoveRequestHeader 移除请求头 RemoveRequestHeader = 头名 - RemoveRequestHeader=Cookie
RemoveResponseHeader 移除响应头 RemoveResponseHeader = 头名 - RemoveResponseHeader=X-Powered-By
SetRequestHeader 覆盖请求头(无则添加) SetRequestHeader = 头名,头值 - SetRequestHeader=Content-Type,application/json
SetResponseHeader 覆盖响应头(无则添加) SetResponseHeader = 头名,头值 - SetResponseHeader=Cache-Control,no-cache
RewriteResponseHeader 正则替换响应头值 RewriteResponseHeader = 头名,正则,替换值 - RewriteResponseHeader=Location,http://old.com,https://new.com

示例:给请求添加来源头,移除响应的敏感头

yaml

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: header-demo
          uri: lb://user-service
          predicates:
            - Path=/user/**
          filters:
            - AddRequestHeader=X-Gateway-Id,user-route-01
            - RemoveResponseHeader=X-Powered-By # 隐藏服务技术栈

2. 路径重写(最常用)

用于修改请求路径,解决 "网关路径与服务实际路径不一致" 问题(如网关 /api/user/** 转发到服务 /user/**)。

过滤器名 作用 参数格式 说明
RewritePath 正则替换请求路径 RewritePath = 原始正则,目标路径 $n 表示原始路径中第 n 个分组(正则捕获)

核心规则

  • 原始正则:匹配网关接收的路径(如 /api/(?<segment>.*)(?<segment>.*) 是命名分组,也可简化为 (.*))。
  • 目标路径:替换后的路径(如 /$\{segment}/$1,注意 YAML 中 $ 需转义为 $\)。

示例 1 :网关路径 /api/user/1 转发到服务 /user/1

yaml

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: rewrite-path-demo
          uri: lb://user-service
          predicates:
            - Path=/api/user/** # 匹配网关路径
          filters:
            # 正则:/api/(user/.*) → 分组1为 user/.*;目标路径:/$1 → 替换为 /user/.*
            - RewritePath=/api/(user/.*),/$\{1}

示例 2 :统一前缀裁剪(网关 /gateway/** 转发到服务 /

yaml

复制代码
filters:
  - RewritePath=/gateway/(?<segment>.*),/$\{segment} # /gateway/hello → /hello

3. 路径前缀操作

简化路径重写,支持 "添加前缀" 或 "移除前缀",比 RewritePath 更简洁。

过滤器名 作用 参数格式 示例
PrefixPath 给请求路径添加前缀(转发到服务时) PrefixPath = 前缀 - PrefixPath=/user(网关 /1 → 服务 /user/1
StripPrefix 移除路径前缀(从左到右移除 N 级) StripPrefix=N(N 为整数) - StripPrefix=1(网关 /api/1 → 服务 /1

示例 1 :StripPrefix(移除 1 级前缀)网关路径 /user/api/1 → 服务路径 /api/1(移除 /user 前缀):

yaml

复制代码
routes:
  - id: strip-prefix-demo
    uri: lb://user-service
    predicates:
      - Path=/user/**
    filters:
      - StripPrefix=1 # 移除第1级前缀(/user)

示例 2 :PrefixPath(添加前缀)网关路径 /1 → 服务路径 /user/1(添加 /user 前缀):

yaml

复制代码
routes:
  - id: prefix-path-demo
    uri: lb://user-service
    predicates:
      - Path=/**
    filters:
      - PrefixPath=/user # 添加前缀 /user

4. 超时配置

控制请求的超时时间(连接超时、响应超时),避免网关因服务响应慢而阻塞。

过滤器名 作用 参数格式 示例
RequestTimeoute 设置请求超时时间 RequestTimeoute = 超时时间(如 3s) - RequestTimeoute=3000ms(3 秒超时)

示例:设置 3 秒超时,超时后网关返回 504 Gateway Timeout:

yaml

复制代码
routes:
  - id: timeout-demo
    uri: lb://slow-service
    predicates:
      - Path=/slow/**
    filters:
      - RequestTimeoute=3s # 支持 s(秒)、ms(毫秒)

5. 重试机制

当服务暂时不可用(如 5xx 错误、连接超时)时,自动重试请求,提高可用性。

过滤器名 作用 参数格式(多参数用逗号分隔) 说明
Retry 配置重试策略 Retry = 重试次数,状态码,方法,延迟时间,最大延迟,因子 可选参数:- 重试次数(默认 3)- 触发重试的状态码(如 503)- 触发重试的 HTTP 方法(如 GET)- 初始延迟(默认 10ms)- 最大延迟(默认 1s)- 延迟因子(默认 2,指数退避)

示例:GET 请求遇到 503/504 时,重试 2 次(初始延迟 100ms,指数退避):

yaml

复制代码
routes:
  - id: retry-demo
    uri: lb://user-service
    predicates:
      - Path=/user/**
    filters:
      - Retry=2,503,504,GET,100ms,1s,2
      # 含义:重试2次,仅对 GET 方法、状态码 503/504 触发,初始延迟100ms,最大延迟1s,延迟因子2(100ms → 200ms → 400ms,不超过1s)

6. 重定向

将请求重定向到其他 URL(如 HTTP 转 HTTPS、旧路径重定向到新路径)。

过滤器名 作用 参数格式 示例
RedirectTo 重定向(支持 3xx 状态码) RedirectTo = 状态码,目标 URL - RedirectTo=302,https://new-domain.com${path}

参数说明

  • 状态码:301(永久重定向)、302(临时重定向)。
  • 目标 URL:支持占位符 ${path}(原始路径)、${query}(原始查询参数)。

示例 1:HTTP 转 HTTPS

yaml

复制代码
routes:
  - id: http-to-https
    uri: http://localhost:8080
    predicates:
      - Path=/**
      - Scheme=http # 仅匹配 HTTP 请求
    filters:
      - RedirectTo=302,https://$\{host}${path}${query} # 重定向到 HTTPS 同路径

示例 2:旧路径重定向到新路径

yaml

复制代码
routes:
  - id: old-to-new-path
    uri: http://localhost:8080
    predicates:
      - Path=/old/**
    filters:
      - RedirectTo=301,/new$\{path} # /old/1 → /new/old/1

7. 限流(Rate Limiting)

限制单位时间内的请求数,保护后端服务,基于 Spring Cloud Gateway 集成的限流组件(如 Redis)。

前置条件:
  1. 引入 Redis 依赖(限流需要 Redis 存储计数器):

xml

复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
  1. 配置 Redis 连接:

yaml

复制代码
spring:
  redis:
    host: localhost
    port: 6379
    password: 123456
限流过滤器:RequestRateLimiter
过滤器名 作用 参数格式 说明
RequestRateLimiter 基于令牌桶算法限流 RequestRateLimiter=key-resolver,replenishRate,burstCapacity - key-resolver:限流键解析器(如 IP、用户 ID)- replenishRate:令牌桶填充速率(每秒允许的平均请求数)- burstCapacity:令牌桶最大容量(每秒允许的峰值请求数)
步骤 1:定义限流键解析器(Java 代码)

需自定义 KeyResolver Bean,指定限流维度(如 IP、用户 ID):

java

运行

复制代码
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

@Configuration
public class RateLimitConfig {
    // 基于请求IP限流(最常用)
    @Bean
    public KeyResolver ipKeyResolver() {
        return exchange -> Mono.just(
            exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
        );
    }

    // 基于用户ID限流(需从请求头获取用户ID)
    @Bean
    public KeyResolver userIdKeyResolver() {
        return exchange -> Mono.justOrEmpty(
            exchange.getRequest().getHeader("X-User-Id")
        ).defaultIfEmpty("anonymous"); // 未登录用户设为匿名
    }
}
步骤 2:配置限流过滤器

yaml

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: rate-limit-demo
          uri: lb://user-service
          predicates:
            - Path=/user/**
          filters:
            # 基于IP限流:每秒填充2个令牌,最大容量4个(峰值4QPS)
            - RequestRateLimiter=ipKeyResolver,2,4

限流响应:默认返回 429 Too Many Requests。

8. 其他常用过滤器

过滤器名 作用 示例
SetPath 直接设置请求路径(覆盖原始路径) - SetPath=/fixed-path(所有匹配请求都转发到 /fixed-path
AddRequestParameter 给请求添加查询参数 - AddRequestParameter=type,web(请求添加 ?type=web
RemoveRequestParameter 移除请求查询参数 - RemoveRequestParameter=secret(移除 ?secret=xxx
DedupeResponseHeader 去重响应头(避免重复值) - DedupeResponseHeader=Access-Control-Allow-Credentials,RETAIN_FIRST(保留第一个值)

三、过滤器执行顺序

  1. 同路由的过滤器按 filters 数组中的配置顺序执行(先配置先执行)。
  2. 全局过滤器(GlobalFilter)与单路由过滤器的执行顺序由 @Order 注解或 getOrder() 方法决定(值越小越先执行)。

四、注意事项

  1. 过滤器参数中若包含特殊字符(如 ${}),YAML 配置需转义(如 $\{1} 而非 $1)。
  2. 路径匹配是 "贪婪匹配",路由 ID 需唯一,避免路由冲突。
  3. 限流、重试等过滤器需依赖额外组件(如 Redis),需提前引入依赖并配置。
  4. 尽量使用内置过滤器,避免自定义过滤器带来的维护成本;复杂场景(如自定义业务逻辑)可结合自定义过滤器。

总结

Spring Cloud Gateway 内置过滤器覆盖了路径处理、头操作、超时、重试、限流等核心场景,配置简单灵活。使用时需根据业务需求选择合适的过滤器,按 "路由 ID → 匹配条件 → 过滤器链" 的结构配置,注意执行顺序和参数格式。

如果需要更复杂的逻辑(如自定义权限校验、日志记录),可在内置过滤器基础上扩展自定义 GatewayFilterGlobalFilter

相关推荐
无心水1 小时前
【分布式利器:限流】3、微服务分布式限流:Sentinel集群限流+Resilience4j使用教程
分布式·微服务·架构·sentinel·分布式限流·resilience4j·分布式利器
一起学开源2 小时前
分布式基石:CAP定理与ACID的取舍艺术
分布式·微服务·架构·流程图·软件工程
摇滚侠5 小时前
2025最新 SpringCloud 教程,Nacos-配置中心-数据隔离-动态切换环境,笔记18
java·笔记·spring cloud
TracyCoder1235 小时前
微服务概念理解学习笔记
学习·微服务·架构
q***06296 小时前
springcloud-eureka与gateway简易搭建
spring cloud·eureka·gateway
TracyCoder1236 小时前
微服务框架选型学习笔记
笔记·学习·微服务
摇滚侠6 小时前
2025最新 SpringCloud 教程,Nacos-注册中心 @LoadBalanced 注解式负载均衡,笔记11
笔记·spring cloud·负载均衡
Tadas-Gao7 小时前
Spring Boot 4.0架构革新:构建更精简、更安全、更高效的Java应用
java·spring boot·分布式·微服务·云原生·架构·系统架构
努力发光的程序员7 小时前
互联网大厂Java面试场景:微服务与Spring Cloud技术点解析
spring cloud·grafana·prometheus·微服务架构·jwt·api网关·jaeger