在微服务架构中,API网关常因定制化需求而引入大量自定义过滤器。这不仅导致代码冗余,更增加了维护成本和潜在冲突风险。其实,Spring Cloud Gateway 官方已经内置了30余个功能强大的过滤器,足以覆盖绝大多数路由增强场景,无需重复造轮子。本文将系统梳理这些内置过滤器,通过配置示例与实战场景,帮助你减少80%的重复编码工作。
一、请求相关过滤器
主要作用于转发前的请求修改,如添加、移除或修改请求头、参数等。
作用:转发请求前,给请求添加指定 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值
场景:传递请求来源标识(如 gateway、app),方便下游服务做权限控制或日志追踪。
作用:移除请求中的指定 Header(如敏感信息)。
配置示例:
filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: RemoveRequestHeader
args:
name: Authorization # 移除客户端传来的 Authorization 头
场景:当下游服务不需要客户端直接传递的令牌,而由网关统一处理认证时使用。
作用:覆盖请求中的 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 参数
作用:将源请求头的值映射到另一个新的请求头里。
配置示例:
filters:
- MapRequestHeader=X-User-Id, userId
场景:前端调用网关时携带 X-User-Id 请求头用于认证,但下游服务校验的是 userId 请求头,此过滤器可自动完成映射。
7. RequestSize
作用:限制请求体大小,拒绝请求体超过指定大小的请求。
配置示例:
filters:
- name: RequestSize
args:
maxSize: 10MB # 最大请求体10MB,超过返回413状态码
场景:防止大文件上传压垮后端服务,在网关层进行流量整形。
作用:限制单个请求头的大小。
配置示例:
filters:
- RequestHeaderSize=1000B
说明:若任何请求头的大小超过1000字节,网关将返回 431 状态码的响应。
作用:转发请求时,保留客户端的原始 Host 头(默认会改为下游服务的 Host)。
配置示例:
filters:
- name: PreserveHostHeader # 无参数,直接启用
场景:下游服务依赖 Host 头进行虚拟主机路由、CORS 校验等逻辑处理时使用。
作用:强制修改转发请求的 Host 头为指定值。
配置示例:
filters:
- name: SetRequestHostHeader
args:
host: target-service.com # 强制 Host 头为 target-service.com
11. CacheRequestBody
作用:缓存请求体。HTTP请求体默认只能读取一次,该过滤器将请求体缓存,供后续多个过滤器或组件读取。
配置示例:
filters:
- name: CacheRequestBody
args:
cacheName: requestBodyCache # 缓存名称
场景:当你的自定义全局过滤器需要先读取请求体进行签名校验,然后路由过滤器还需要读取请求体时,必须使用此过滤器。
二、响应相关过滤器
主要作用于服务返回响应后,对响应头、状态码或响应体进行调整。
作用:给响应添加指定 Header。
配置示例:
filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: AddResponseHeader
args:
name: X-Response-Time
value: 120 # 可结合全局过滤器动态设置响应时间
场景:添加 Cache-Control: max-age=3600 控制静态资源缓存,或添加跨域相关 Header。
作用:移除响应中的敏感或多余 Header。
配置示例:
filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: RemoveResponseHeader
args:
name: X-Application-Context
场景:防止 X-Application-Context 等Header暴露内部服务信息,增强安全性。
作用:覆盖响应中的 Header。
配置示例:
filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: SetResponseHeader
args:
name: Content-Encoding
value: gzip # 强制响应使用 gzip 编码
作用:使用正则表达式修改响应 Header 的值。
配置示例:
filters:
- RewritePath=/test/version1/(?<segment>.*),/${segment}
- name: RewriteResponseHeader
args:
name: X-User-Phone
regexp: "(.{3}).*(.{4})" # 保留前3位和后4位
replacement: "$1****$2" # 手机号脱敏为 138****5678
场景:对响应中的敏感信息(如手机号、身份证号)进行脱敏处理。
作用:当响应头存在多个相同名称时,去重并保留指定策略的值。
配置示例:
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并返回自定义友好页面。
作用:重写响应头中的 Location 字段,常用于反向代理场景。策略包含 NEVER_STRIP、AS_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% 的常见需求(如统一添加头信息、路径前缀处理、接口限流、跨域配置等)都可以通过简单的配置完成,无需编写自定义过滤器代码。
合理利用这些内置组件,不仅能极大提升开发效率,减少重复编码,还能降低系统复杂度,提升可维护性。当然,在组合使用多个过滤器时,务必注意它们的配置顺序,错误的顺序可能导致意想不到的结果。希望本文能帮助你在云栈社区的微服务网关实践中,更加游刃有余。