Appearance
GatewayFilter 工厂
在微服务架构中,网关作为系统的入口点,需要对请求和响应进行各种处理,如添加请求头、修改响应状态码、限流、认证等。Spring Cloud Gateway 通过 GatewayFilter Factories 提供了强大而灵活的过滤器机制。
Route filters(路由过滤器)
允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。路由过滤器的作用域限定在特定的路由上。Spring Cloud Gateway 包含许多内置的 GatewayFilter 工厂。
什么是 GatewayFilter Factories?
GatewayFilter Factories 是 Spring Cloud Gateway 中用于创建过滤器的工厂类。这些工厂可以根据配置参数创建相应的过滤器实例,对请求和响应进行处理。
处理流程
核心概念
1. 过滤器类型
Spring Cloud Gateway 中的过滤器分为两大类:
- Pre 过滤器:在请求转发到后端服务之前执行
- Post 过滤器:在从后端服务收到响应之后执行
2. 过滤器作用域
- Route Filter:作用于特定路由
- Global Filter:作用于所有路由
常见过滤器
1. AddRequestHeader 过滤器
业务场景:在微服务调用链中,需要在请求头中添加用户信息、追踪 ID 等元数据。
kotlin
import org.springframework.cloud.gateway.route.RouteLocator
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class GatewayConfig {
@Bean
fun customRoutes(builder: RouteLocatorBuilder): RouteLocator {
return builder.routes()
.route("add-request-header") { r ->
r.path("/api/users/**")
.filters { f ->
f.addRequestHeader("X-Request-Source", "Gateway") // 添加请求头
.addRequestHeader("X-User-Type", "Premium") // 添加用户类型
}
.uri("http://user-service")
}
.build()
}
}yaml
# application.yml 配置方式
spring:
cloud:
gateway:
routes:
- id: add-request-header-route
uri: http://user-service
predicates:
- Path=/api/users/**
filters:
- AddRequestHeader=X-Request-Source, Gateway
- AddRequestHeader=X-User-Type, Premium2. AddResponseHeader 过滤器
业务场景:为响应添加安全头、CORS 头或自定义元数据。
kotlin
@Bean
fun securityHeadersRoute(builder: RouteLocatorBuilder): RouteLocator {
return builder.routes()
.route("security-headers") { r ->
r.path("/api/public/**")
.filters { f ->
f.addResponseHeader("X-Frame-Options", "DENY") // 防止点击劫持
.addResponseHeader("X-Content-Type-Options", "nosniff") // 防止MIME类型嗅探
.addResponseHeader("X-Response-Time", System.currentTimeMillis().toString()) // 响应时间戳
}
.uri("http://public-service")
}
.build()
}3. RewritePath 过滤器
业务场景:API 版本管理,将旧版本的 API 路径重写为新版本。
kotlin
@Bean
fun pathRewriteRoute(builder: RouteLocatorBuilder): RouteLocator {
return builder.routes()
.route("path-rewrite") { r ->
r.path("/v1/api/**")
.filters { f ->
// 将 /v1/api/users 重写为 /v2/api/users
f.rewritePath("/v1/api/(?<segment>.*)", "/v2/api/\${segment}")
}
.uri("http://api-service")
}
.build()
}4. RequestRateLimiter 过滤器
业务场景:限制 API 调用频率,防止系统过载。
kotlin
import org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiter
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver
import reactor.core.publisher.Mono
@Bean
fun rateLimitRoute(builder: RouteLocatorBuilder): RouteLocator {
return builder.routes()
.route("rate-limit") { r ->
r.path("/api/orders/**")
.filters { f ->
f.requestRateLimiter { config ->
config.rateLimiter = redisRateLimiter() // 使用Redis作为限流存储
config.keyResolver = userKeyResolver() // 基于用户ID限流
}
}
.uri("http://order-service")
}
.build()
}
@Bean
fun redisRateLimiter(): RedisRateLimiter {
return RedisRateLimiter(10, 20, 1) // 每秒10个请求,突发20个,每次补充1个令牌
}
@Bean
fun userKeyResolver(): KeyResolver {
return KeyResolver { exchange ->
// 基于用户ID进行限流
Mono.just(exchange.request.headers.getFirst("X-User-Id") ?: "anonymous")
}
}5. Retry 过滤器
业务场景:在网络不稳定的环境中,自动重试失败的请求。
kotlin
@Bean
fun retryRoute(builder: RouteLocatorBuilder): RouteLocator {
return builder.routes()
.route("retry") { r ->
r.path("/api/payment/**")
.filters { f ->
f.retry { config ->
config.retries = 3 // 重试3次
config.statuses = setOf(HttpStatus.BAD_GATEWAY, HttpStatus.SERVICE_UNAVAILABLE)
config.methods = setOf(HttpMethod.GET, HttpMethod.POST) // 只对GET和POST重试
config.backoff = RetryGatewayFilterFactory.BackoffConfig().apply {
firstBackoff = Duration.ofMillis(100) // 首次重试间隔100ms
maxBackoff = Duration.ofSeconds(2) // 最大重试间隔2s
factor = 2.0 // 指数退避因子
}
}
}
.uri("http://payment-service")
}
.build()
}6. CircuitBreaker 过滤器
业务场景:在下游服务不可用时,快速失败并提供降级响应。
kotlin
@Bean
fun circuitBreakerRoute(builder: RouteLocatorBuilder): RouteLocator {
return builder.routes()
.route("circuit-breaker") { r ->
r.path("/api/recommendations/**")
.filters { f ->
f.circuitBreaker { config ->
config.name = "recommendationCircuitBreaker" // 断路器名称
config.fallbackUri = "forward:/fallback/recommendations" // 降级URI
}
}
.uri("http://recommendation-service")
}
.build()
}
// 降级处理器
@RestController
class FallbackController {
@GetMapping("/fallback/recommendations")
fun recommendationFallback(): ResponseEntity<Map<String, Any>> {
val fallbackResponse = mapOf(
"message" to "推荐服务暂时不可用,为您提供默认推荐",
"recommendations" to listOf("热门商品1", "热门商品2", "热门商品3"),
"timestamp" to System.currentTimeMillis()
)
return ResponseEntity.ok(fallbackResponse)
}
}自定义 GatewayFilter Factory
当内置过滤器无法满足需求时,可以创建自定义的过滤器工厂。
业务场景:请求日志记录
kotlin
import org.springframework.cloud.gateway.filter.GatewayFilter
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory
import org.springframework.stereotype.Component
import reactor.core.publisher.Mono
import org.slf4j.LoggerFactory
@Component
class RequestLoggingGatewayFilterFactory :
AbstractGatewayFilterFactory<RequestLoggingGatewayFilterFactory.Config>() {
private val logger = LoggerFactory.getLogger(RequestLoggingGatewayFilterFactory::class.java)
override fun apply(config: Config): GatewayFilter {
return GatewayFilter { exchange, chain ->
val request = exchange.request
val startTime = System.currentTimeMillis()
logger.info(
"请求开始 - 方法: {}, 路径: {}, 客户端IP: {}, User-Agent: {}",
request.method,
request.path,
getClientIp(exchange),
request.headers.getFirst("User-Agent")
)
chain.filter(exchange).then(
Mono.fromRunnable {
val endTime = System.currentTimeMillis()
val response = exchange.response
logger.info(
"请求完成 - 状态码: {}, 耗时: {}ms, 路径: {}",
response.statusCode,
endTime - startTime,
request.path
)
}
)
}
}
private fun getClientIp(exchange: org.springframework.web.server.ServerWebExchange): String {
val request = exchange.request
return request.headers.getFirst("X-Forwarded-For")
?: request.headers.getFirst("X-Real-IP")
?: request.remoteAddress?.address?.hostAddress
?: "unknown"
}
override fun getConfigClass(): Class<Config> = Config::class.java
class Config {
var includeHeaders: Boolean = false // 是否包含请求头信息
var includeBody: Boolean = false // 是否包含请求体信息
}
}使用自定义过滤器
kotlin
@Bean
fun customLoggingRoute(builder: RouteLocatorBuilder): RouteLocator {
return builder.routes()
.route("logging") { r ->
r.path("/api/**")
.filters { f ->
f.filter(RequestLoggingGatewayFilterFactory().apply(
RequestLoggingGatewayFilterFactory.Config().apply {
includeHeaders = true // 包含请求头
includeBody = false // 不包含请求体
}
))
}
.uri("http://backend-service")
}
.build()
}过滤器链执行顺序
过滤器的执行顺序可以通过 @Order 注解或实现 Ordered 接口来控制:
kotlin
@Component
@Order(-1) // 数值越小,优先级越高
class HighPriorityFilter : GlobalFilter, Ordered {
override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain): Mono<Void> {
// 高优先级过滤器逻辑
return chain.filter(exchange)
}
override fun getOrder(): Int = -1
}过滤器执行顺序示意图
配置方式对比
1. YAML 配置方式
适合简单的过滤器配置,配置清晰直观
yaml
spring:
cloud:
gateway:
routes:
- id: example-route
uri: http://example.com
predicates:
- Path=/api/**
filters:
- AddRequestHeader=X-Source, Gateway
- AddResponseHeader=X-Powered-By, Spring Cloud Gateway
- RewritePath=/api/(?<segment>.*), /${segment}2. Kotlin 配置方式
适合复杂的过滤器配置,支持动态配置和条件逻辑
kotlin
@Bean
fun complexRoute(builder: RouteLocatorBuilder): RouteLocator {
return builder.routes()
.route { r ->
r.path("/api/**")
.and().header("X-User-Type", "premium") // 条件组合
.filters { f ->
f.addRequestHeader("X-Priority", "high")
.requestRateLimiter { config ->
config.rateLimiter = premiumUserRateLimiter()
config.keyResolver = userKeyResolver()
}
}
.uri("http://premium-service")
}
.build()
}最佳实践
1. 性能优化
TIP
- 避免在过滤器中进行阻塞操作
- 合理设置过滤器执行顺序
- 使用异步非阻塞的方式处理请求
kotlin
// ❌ 错误示例:阻塞操作
override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain): Mono<Void> {
Thread.sleep(1000) // 阻塞操作,会影响性能
return chain.filter(exchange)
}
// ✅ 正确示例:异步操作
override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain): Mono<Void> {
return Mono.delay(Duration.ofSeconds(1)) // 非阻塞延迟
.then(chain.filter(exchange))
}2. 错误处理
kotlin
override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain): Mono<Void> {
return chain.filter(exchange)
.onErrorResume { throwable ->
logger.error("过滤器执行异常", throwable)
// 返回错误响应
val response = exchange.response
response.statusCode = HttpStatus.INTERNAL_SERVER_ERROR
response.setComplete()
}
}3. 监控和观测
kotlin
@Component
class MetricsFilter : GlobalFilter {
private val meterRegistry: MeterRegistry = Metrics.globalRegistry
override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain): Mono<Void> {
val timer = Timer.start(meterRegistry)
return chain.filter(exchange)
.doFinally {
timer.stop(Timer.builder("gateway.request.duration")
.tag("path", exchange.request.path.value())
.tag("method", exchange.request.method.toString())
.register(meterRegistry))
}
}
}常见问题与解决方案
1. 过滤器不生效
检查过滤器的注册和路由匹配条件
kotlin
// 确保过滤器已注册为Bean
@Component
class MyCustomFilter : GlobalFilter {
// 实现逻辑
}
// 确保路由条件正确匹配
.route { r ->
r.path("/api/**") // 检查路径匹配规则
.filters { f -> f.myCustomFilter() }
}2. 过滤器执行顺序问题
kotlin
// 使用Order注解控制执行顺序
@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
class AuthenticationFilter : GlobalFilter3. 内存泄漏问题
kotlin
// 正确处理资源释放
override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain): Mono<Void> {
return chain.filter(exchange)
.doFinally { signalType ->
// 清理资源
cleanup()
}
}总结
Spring Cloud Gateway 的 GatewayFilter Factories 提供了强大的请求和响应处理能力:
- 内置过滤器:涵盖了大部分常见的网关功能需求
- 自定义扩展:支持创建自定义过滤器满足特殊业务需求
- 配置灵活:支持 YAML 和代码两种配置方式
- 性能优秀:基于 WebFlux 的响应式编程模型,支持高并发
通过合理使用这些过滤器,可以构建出功能强大、性能优秀的微服务网关系统。