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 → 匹配条件 → 过滤器链” 的结构配置,注意执行顺序和参数格式。

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值