找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

549

积分

0

好友

69

主题
发表于 前天 07:56 | 查看: 8| 回复: 0

在微服务架构中,API网关常因定制化需求而引入大量自定义过滤器。这不仅导致代码冗余,更增加了维护成本和潜在冲突风险。其实,Spring Cloud Gateway 官方已经内置了30余个功能强大的过滤器,足以覆盖绝大多数路由增强场景,无需重复造轮子。本文将系统梳理这些内置过滤器,通过配置示例与实战场景,帮助你减少80%的重复编码工作。

一、请求相关过滤器

主要作用于转发前的请求修改,如添加、移除或修改请求头、参数等。

1. AddRequestHeader

作用:转发请求前,给请求添加指定 Header。
配置示例

spring:
  cloud:
    gateway:
      routes:
      - id: xiaofu-120412
        uri: http://127.0.0.1:12041/
        predicates:
        - Weight=xiaofu-group, 1
        - Path=/test/version1/**
        filters:
        - RewritePath=/test/version1/(?<segment>.*),/${segment}
        - name: AddRequestHeader
          args:
            name: X-Request-Source # Header名称
            value: gateway # Header值

场景:传递请求来源标识(如 gatewayapp),方便下游服务做权限控制或日志追踪。

2. RemoveRequestHeader

作用:移除请求中的指定 Header(如敏感信息)。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: RemoveRequestHeader
  args:
    name: Authorization # 移除客户端传来的 Authorization 头

场景:当下游服务不需要客户端直接传递的令牌,而由网关统一处理认证时使用。

3. SetRequestHeader

作用:覆盖请求中的 Header。若请求中已存在指定 Header,直接覆盖其值;不存在则添加。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: SetRequestHeader
  args:
    name: Authorization
    value: 111111 # 强制将 Authorization 设为 111111

注意:与 AddRequestHeader 的区别是,SetRequestHeader 会覆盖原有值,而 AddRequestHeader 会保留原有值(若存在则新增一个同名Header,可能导致重复)。

4. AddRequestParameter

作用:转发请求时给请求添加参数,支持在 URL 或请求体中添加参数(适用于 GET/POST)。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: AddRequestParameter
  args:
    name: from
    value: gateway # 所有请求会带上 ?from=gateway 参数

场景:用于统计请求来源,或给下游服务传递额外标识(如灰度标记、渠道号)。

5. RemoveRequestParameter

作用:移除请求中的指定参数(如敏感参数 password)。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: RemoveRequestParameter
  args:
    name: password # 移除请求中的 password 参数

6. MapRequestHeader

作用:将源请求头的值映射到另一个新的请求头里。
配置示例

filters:
- MapRequestHeader=X-User-Id, userId

场景:前端调用网关时携带 X-User-Id 请求头用于认证,但下游服务校验的是 userId 请求头,此过滤器可自动完成映射。

7. RequestSize

作用:限制请求体大小,拒绝请求体超过指定大小的请求。
配置示例

filters:
- name: RequestSize
  args:
    maxSize: 10MB # 最大请求体10MB,超过返回413状态码

场景:防止大文件上传压垮后端服务,在网关层进行流量整形。

8. RequestHeaderSize

作用:限制单个请求头的大小。
配置示例

filters:
- RequestHeaderSize=1000B

说明:若任何请求头的大小超过1000字节,网关将返回 431 状态码的响应。

9. PreserveHostHeader

作用:转发请求时,保留客户端的原始 Host 头(默认会改为下游服务的 Host)。
配置示例

filters:
- name: PreserveHostHeader # 无参数,直接启用

场景:下游服务依赖 Host 头进行虚拟主机路由、CORS 校验等逻辑处理时使用。

10. SetRequestHostHeader

作用:强制修改转发请求的 Host 头为指定值。
配置示例

filters:
- name: SetRequestHostHeader
  args:
    host: target-service.com # 强制 Host 头为 target-service.com

11. CacheRequestBody

作用:缓存请求体。HTTP请求体默认只能读取一次,该过滤器将请求体缓存,供后续多个过滤器或组件读取。
配置示例

filters:
  - name: CacheRequestBody
    args:
      cacheName: requestBodyCache # 缓存名称

场景:当你的自定义全局过滤器需要先读取请求体进行签名校验,然后路由过滤器还需要读取请求体时,必须使用此过滤器。

二、响应相关过滤器

主要作用于服务返回响应后,对响应头、状态码或响应体进行调整。

1. AddResponseHeader

作用:给响应添加指定 Header。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: AddResponseHeader
  args:
    name: X-Response-Time
    value: 120 # 可结合全局过滤器动态设置响应时间

场景:添加 Cache-Control: max-age=3600 控制静态资源缓存,或添加跨域相关 Header。

2. RemoveResponseHeader

作用:移除响应中的敏感或多余 Header。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: RemoveResponseHeader
  args:
    name: X-Application-Context

场景:防止 X-Application-Context 等Header暴露内部服务信息,增强安全性。

3. SetResponseHeader

作用:覆盖响应中的 Header。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: SetResponseHeader
  args:
    name: Content-Encoding
    value: gzip # 强制响应使用 gzip 编码

4. RewriteResponseHeader

作用:使用正则表达式修改响应 Header 的值。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: RewriteResponseHeader
  args:
    name: X-User-Phone
    regexp: "(.{3}).*(.{4})" # 保留前3位和后4位
    replacement: "$1****$2" # 手机号脱敏为 138****5678

场景:对响应中的敏感信息(如手机号、身份证号)进行脱敏处理。

5. DedupeResponseHeader

作用:当响应头存在多个相同名称时,去重并保留指定策略的值。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: DedupeResponseHeader
  args:
    name: Access-Control-Allow-Origin
    strategy: RETAIN_FIRST # 保留第一个值

场景:解决因多层代理或配置不当导致的 Access-Control-Allow-Origin 等跨域头重复的问题。

6. RemoveJsonAttributesResponseBody

作用:从根层 JSON 响应体中移除指定字段。仅对 Content-Type: application/json 的响应生效。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- RemoveJsonAttributesResponseBody=xiaofu

场景:下游服务返回的某些敏感或无意义字段暂时无法改动,可在网关层过滤掉。注意:此过滤器在 2021.x 版本中可能不支持,需要较高版本。

7. SetStatus

作用:强制修改响应的 HTTP 状态码。
配置示例

filters:
- name: SetStatus
  args:
    status: 200 # 无论下游服务返回什么,网关响应状态码都设为 200

场景:统一错误码格式,或将特定的错误状态(如404)转换为200并返回自定义友好页面。

8. RewriteLocationResponseHeader

作用:重写响应头中的 Location 字段,常用于反向代理场景。策略包含 NEVER_STRIPAS_IN_REQUEST(默认)和 ALWAYS_STRIP

  • NEVER_STRIP: 即使原始请求路径不包含版本前缀,也不会被剥离。
  • AS_IN_REQUEST: 只有当原始请求路径不包含版本前缀时,才会剥离响应Location头中的版本前缀。
  • ALWAYS_STRIP: 版本前缀总是被剥离,即使原始请求路径包含它。
    配置示例
    
    filters:
  • RewriteLocationResponseHeader=AS_IN_REQUEST, Location, /v2/
    
    ### 三、路径处理相关过滤器

用于修改请求路径、添加/移除前缀或执行重定向。

1. RewritePath(最常用)

作用:使用正则表达式修改请求路径。
配置示例

filters:
- name: RewritePath
  args:
    regexp: /api/(?<segment>.*) # 匹配 /api/test
    replacement: /${segment} # 重写为 /test(转发到下游服务)

场景:前端所有请求带 /api 前缀,但下游服务接口没有此前缀,网关转发时将其去掉。

2. PrefixPath

作用:给请求路径添加指定前缀。
配置示例

filters:
- name: PrefixPath
  args:
    prefix: /v1 # 请求 /user → 转发到 /v1/user

3. StripPrefix

作用:移除路径中指定数量的前缀段。
配置示例

filters:
- name: StripPrefix
  args:
    parts: 2 # /api/v1/user → 转发到 /user

注意:与 RewritePath 的区别是,StripPrefix段数移除,RewritePath 按正则匹配,后者更灵活。

4. RedirectTo

作用:将请求重定向到指定 URL(支持 301/302 状态码)。
配置示例

filters:
- name: RedirectTo
  args:
    status: 302 # 临时重定向
    url: https://baidu.com # 重定向到新地址

场景:旧接口废弃、域名迁移时,引导用户或客户端访问新地址。

5. SetPath

作用:使用模板语法直接设置请求路径,替代原有路径。
配置示例

filters:
- name: SetPath
  args:
    template: /fixed/path # 所有匹配此路由的请求都转发到 /fixed/path

四、安全与容错相关过滤器

提供限流、重试、熔断等保障微服务稳定性的能力。

1. RequestRateLimiter

作用:基于令牌桶算法对请求进行限流,默认使用 Redis 存储限流计数。
配置示例

filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: RequestRateLimiter
  args:
    redis-rate-limiter.replenishRate: 10 # 令牌桶填充速率(每秒10个)
    redis-rate-limiter.burstCapacity: 20 # 令牌桶最大容量(最多存20个)
    key-resolver: "#{@myKeyResolver}" # 需自定义 KeyResolver Bean

key-resolver 用于定义限流键的生成规则,例如基于IP、用户ID等。
自定义KeyResolver示例:

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component("myKeyResolver")
public class MyKeyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        // 例如,根据请求头中的x-api-key生成key
        return Mono.just("8888888x-api-key:"+exchange.getRequest().getHeaders().getFirst("x-api-key"));
    }
}

同时需要配置Redis连接信息:

spring:
  redis:
    host: localhost
    port: 6379
    password: xxxx

场景:保护下游服务,防止流量过载,如对秒杀接口进行单IP或用户维度的频率限制。

2. Retry

作用:当下游服务返回指定状态码或发生超时时,自动重试请求。
配置示例

filters:
- name: Retry
  args:
    retries: 3 # 最多重试3次
    statuses: BAD_GATEWAY, SERVICE_UNAVAILABLE # 遇到 502/503 状态码重试
    methods: GET,POST
    backoff:
      firstBackoff: 100ms # 第一次重试延迟100ms
      maxBackoff: 1s # 最大延迟1s
      factor: 2 # 延迟倍数(100ms → 200ms → 400ms)
      basedOnPreviousValue: false

注意:重试可能导致下游服务重复处理(非幂等操作),务必确保接口的幂等性。

3. Hystrix

作用:熔断降级(已过时,推荐使用 CircuitBreaker)。当下游服务调用超时或失败时,触发熔断并返回降级响应。
配置示例

filters:
- name: Hystrix
  args:
    name: fallbackCommand # 熔断命令名
    fallbackUri: forward:/fallback # 降级接口URI(网关内部)

4. CircuitBreaker

作用:熔断降级(替代 Hystrix),基于 Resilience4j 实现,支持超时、失败率阈值等配置。
配置示例(熔断后转发到网关内部接口):

spring:
  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: http://127.0.0.1:12041/
        predicates:
        - Path=//ingredients/**
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis # 转发到网关内的控制器

网关内降级控制器示例:

@RestController
@RequestMapping("/")
@Slf4j
public class InCaseOfFailureUseThisController {
    @GetMapping(value = "/inCaseOfFailureUseThis")
    public String inCaseOfFailureUseThis() {
        System.out.println("inCaseOfFailureUseThis");
        return "inCaseOfFailureUseThis";
    }
}

也可以配置熔断后重定向到外部服务:

spring:
  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: http://127.0.0.1:12041/
        predicates:
        - Path=//ingredients/**
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/fallback
      - id: myCircuitBreaker-fallback # 定义专门处理降级的路由
        uri: http://localhost:9994 # 外部降级服务
        predicates:
        - Path=/fallback

5. SaveSession

作用:在转发调用下游服务之前,强制进行 WebSession::save 操作。
配置示例

filters:
- SaveSession

场景:在使用 Spring Session 等懒加载会话存储时,确保会话状态(如 Spring Security 的认证信息)在转发前已持久化,对下游服务可见。

总结

Spring Cloud Gateway 内置的过滤器体系非常完善,涵盖了请求/响应处理、路径重写、安全限流、容错熔断等核心网关功能。在实际开发中,80% 的常见需求(如统一添加头信息、路径前缀处理、接口限流、跨域配置等)都可以通过简单的配置完成,无需编写自定义过滤器代码。

合理利用这些内置组件,不仅能极大提升开发效率,减少重复编码,还能降低系统复杂度,提升可维护性。当然,在组合使用多个过滤器时,务必注意它们的配置顺序,错误的顺序可能导致意想不到的结果。希望本文能帮助你在云栈社区的微服务网关实践中,更加游刃有余。




上一篇:Ralph循环:用无限迭代改写AI编程范式
下一篇:开源API工具Hoppscotch评测:支持GraphQL/WebSocket的Postman替代方案
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-24 01:38 , Processed in 0.501406 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表