Spring Cloud Gateway 全局过滤器深度解析

Spring Cloud Gateway 全局过滤器深度解析

全局过滤器概述

在 Spring Cloud Gateway 中,全局过滤器(GlobalFilter)是一种特殊类型的过滤器,它们会被有条件地应用到所有路由上。与路由特定的GatewayFilter不同,全局过滤器不需要在每个路由配置中显式声明,这使得它们非常适合实现跨路由的通用逻辑。

全局过滤器的接口签名与GatewayFilter相同,这意味着它们可以无缝集成到网关的过滤链中。需要注意的是,这个接口及其使用方式在未来的里程碑版本中可能会发生变化。

过滤器执行顺序机制

组合过滤链的排序原理

当一个请求匹配到路由时,网关的过滤处理程序会将所有GlobalFilter实例和特定于路由的GatewayFilter实例组合成一个过滤链。这个组合后的过滤链会根据org.springframework.core.Ordered接口进行排序,开发者可以通过实现getOrder()方法来设置过滤器的执行顺序。

Spring Cloud Gateway 将过滤逻辑的执行分为"pre"(前置)和"post"(后置)两个阶段:

  • 在"pre"阶段,优先级最高的过滤器最先执行
  • 在"post"阶段,优先级最高的过滤器最后执行

自定义全局过滤器示例

以下是一个自定义全局过滤器的实现示例,展示了如何通过实现GlobalFilterOrdered接口来创建并配置一个全局过滤器:

@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:路由ID
  • routeUri:路由目标URI
  • outcome:基于HTTP状态系列的分类结果
  • status:返回给客户端的HTTP状态
  • httpStatusCode:返回给客户端的HTTP状态码
  • httpMethod:请求使用的HTTP方法

额外配置:通过设置spring.cloud.gateway.metrics.tags.path.enabledtrue(默认为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具有httphttps方案时,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具有wswss方案时,WebSocket路由过滤器会运行。它使用Spring WebSocket基础设施来转发WebSocket请求。

负载均衡:可以通过在URI前添加lb前缀来实现WebSocket的负载均衡,如lb:ws://serviceid

标记已路由的交换

网关路由一个ServerWebExchange后,会通过向交换属性添加gatewayAlreadyRouted来将其标记为"已路由"。一旦请求被标记为已路由,其他路由过滤器将不会再次路由该请求。

实用方法

  • ServerWebExchangeUtils.isAlreadyRouted:检查交换是否已被路由
  • ServerWebExchangeUtils.setAlreadyRouted:将交换标记为已路由

最佳实践与注意事项

  1. 性能考虑:全局过滤器会应用于所有请求,因此在实现时应特别注意性能影响,避免在过滤器中执行耗时操作。

  2. 异常处理:在自定义全局过滤器中,应妥善处理异常情况,确保不会导致请求挂起或网关崩溃。

  3. 缓存策略:使用本地响应缓存时,应根据业务场景合理设置缓存大小和生存时间,避免内存问题或数据不一致。

  4. 监控集成:充分利用网关指标过滤器提供的数据,构建完整的监控体系,及时发现和解决性能问题。

  5. 负载均衡:在使用负载均衡功能时,确保服务发现配置正确,并考虑实现自定义的负载均衡策略以满足特定需求。

通过深入理解和合理配置这些全局过滤器,开发者可以充分发挥Spring Cloud Gateway的强大功能,构建高效、可靠的API网关服务。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沈如廷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值