Spring Cloud Gateway 全局过滤器深度解析
全局过滤器概述
在 Spring Cloud Gateway 中,全局过滤器(GlobalFilter
)是一种特殊类型的过滤器,它们会被有条件地应用到所有路由上。与路由特定的GatewayFilter
不同,全局过滤器不需要在每个路由配置中显式声明,这使得它们非常适合实现跨路由的通用逻辑。
全局过滤器的接口签名与GatewayFilter
相同,这意味着它们可以无缝集成到网关的过滤链中。需要注意的是,这个接口及其使用方式在未来的里程碑版本中可能会发生变化。
过滤器执行顺序机制
组合过滤链的排序原理
当一个请求匹配到路由时,网关的过滤处理程序会将所有GlobalFilter
实例和特定于路由的GatewayFilter
实例组合成一个过滤链。这个组合后的过滤链会根据org.springframework.core.Ordered
接口进行排序,开发者可以通过实现getOrder()
方法来设置过滤器的执行顺序。
Spring Cloud Gateway 将过滤逻辑的执行分为"pre"(前置)和"post"(后置)两个阶段:
- 在"pre"阶段,优先级最高的过滤器最先执行
- 在"post"阶段,优先级最高的过滤器最后执行
自定义全局过滤器示例
以下是一个自定义全局过滤器的实现示例,展示了如何通过实现GlobalFilter
和Ordered
接口来创建并配置一个全局过滤器:
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("custom global filter");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
在这个例子中,getOrder()
返回-1表示这个过滤器将有较高的优先级(较小的order值意味着更高的优先级)。
核心全局过滤器详解
1. 网关指标过滤器
启用方式:添加spring-boot-starter-actuator
依赖,默认情况下只要不将spring.cloud.gateway.metrics.enabled
设为false
,网关指标过滤器就会自动运行。
指标详情:该过滤器会添加名为spring.cloud.gateway.requests
的计时器指标,包含以下标签:
routeId
:路由IDrouteUri
:路由目标URIoutcome
:基于HTTP状态系列的分类结果status
:返回给客户端的HTTP状态httpStatusCode
:返回给客户端的HTTP状态码httpMethod
:请求使用的HTTP方法
额外配置:通过设置spring.cloud.gateway.metrics.tags.path.enabled
为true
(默认为false
)可以激活包含路径标签的额外指标。
集成提示:这些指标可以从/actuator/metrics/spring.cloud.gateway.requests
端点获取,非常适合与Prometheus和Grafana集成构建监控看板。
2. 本地响应缓存过滤器
启用条件:当相关属性启用时,LocalResponseCache
过滤器会运行:
spring.cloud.gateway.global-filter.local-response-cache.enabled
:为所有路由激活全局缓存spring.cloud.gateway.filter.local-response-cache.enabled
:在路由级别激活关联过滤器
缓存条件:该特性使用Caffeine为满足以下条件的响应启用本地缓存:
- 请求是无体的GET请求
- 响应状态码为:HTTP 200、206或301
- HTTP
Cache-Control
头允许缓存
配置参数:
size
:设置缓存的最大大小(支持KB、MB和GB单位)time-to-live
:设置缓存条目的生存时间(支持s、m、h单位)
自动计算:该过滤器还会自动计算HTTP Cache-Control
头中的max-age
值,如果原始响应中存在max-age
,则会根据配置的timeToLive
参数重写该值。
3. 转发路由过滤器
ForwardRoutingFilter
会检查交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
中的URI。如果URL具有forward
方案(如forward:///localendpoint
),它会使用Spring的DispatcherHandler
来处理请求。请求URL的路径部分会被转发URL中的路径覆盖。
4. Netty路由过滤器
当交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
中的URL具有http
或https
方案时,Netty路由过滤器会运行。它使用Netty的HttpClient
来发起下游代理请求。
5. 响应式负载均衡客户端过滤器
ReactiveLoadBalancerClientFilter
会查找交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
中的URI。如果URL具有lb
方案(如lb://myservice
),它会使用Spring Cloud的ReactorLoadBalancer
将名称解析为实际的主机和端口。
重要提示:默认情况下,当ReactorLoadBalancer
找不到服务实例时,会返回503。可以通过设置spring.cloud.gateway.loadbalancer.use404=true
来改为返回404。
6. WebSocket路由过滤器
当交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
中的URL具有ws
或wss
方案时,WebSocket路由过滤器会运行。它使用Spring WebSocket基础设施来转发WebSocket请求。
负载均衡:可以通过在URI前添加lb
前缀来实现WebSocket的负载均衡,如lb:ws://serviceid
。
标记已路由的交换
网关路由一个ServerWebExchange
后,会通过向交换属性添加gatewayAlreadyRouted
来将其标记为"已路由"。一旦请求被标记为已路由,其他路由过滤器将不会再次路由该请求。
实用方法:
ServerWebExchangeUtils.isAlreadyRouted
:检查交换是否已被路由ServerWebExchangeUtils.setAlreadyRouted
:将交换标记为已路由
最佳实践与注意事项
-
性能考虑:全局过滤器会应用于所有请求,因此在实现时应特别注意性能影响,避免在过滤器中执行耗时操作。
-
异常处理:在自定义全局过滤器中,应妥善处理异常情况,确保不会导致请求挂起或网关崩溃。
-
缓存策略:使用本地响应缓存时,应根据业务场景合理设置缓存大小和生存时间,避免内存问题或数据不一致。
-
监控集成:充分利用网关指标过滤器提供的数据,构建完整的监控体系,及时发现和解决性能问题。
-
负载均衡:在使用负载均衡功能时,确保服务发现配置正确,并考虑实现自定义的负载均衡策略以满足特定需求。
通过深入理解和合理配置这些全局过滤器,开发者可以充分发挥Spring Cloud Gateway的强大功能,构建高效、可靠的API网关服务。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考