SpringCloud Gateway自带的全局过滤器GlobalFilter是怎样的

发布时间:2021-09-29 14:04:16 作者:柒染
来源:亿速云 阅读:759
# SpringCloud Gateway自带的全局过滤器GlobalFilter是怎样的

## 一、前言

SpringCloud Gateway作为SpringCloud生态中的API网关组件,其核心功能之一就是通过过滤器(Filter)机制对请求和响应进行精细化控制。其中**全局过滤器(GlobalFilter)**作为所有路由共享的过滤器,在网关功能扩展中扮演着关键角色。本文将深入剖析SpringCloud Gateway内置的全局过滤器实现原理、执行机制以及典型应用场景。

## 二、GlobalFilter基础概念

### 2.1 过滤器类型对比

SpringCloud Gateway包含三种过滤器类型:

| 类型            | 作用范围       | 执行顺序控制       | 典型应用场景         |
|-----------------|--------------|------------------|--------------------|
| GatewayFilter   | 特定路由       | 通过配置显式指定    | 路由级别的请求修改     |
| GlobalFilter    | 全局所有路由    | 实现Ordered接口   | 认证、日志、流量控制   |
| DefaultFilters  | 路由组默认配置  | 配置时指定顺序      | 一组路由的公共处理逻辑 |

### 2.2 GlobalFilter核心特性

```java
public interface GlobalFilter {
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
  1. 全局生效:自动应用于所有路由请求
  2. 责任链模式:通过GatewayFilterChain实现多过滤器串联执行
  3. 响应式支持:基于Reactor的Mono返回值
  4. 顺序可控:配合Ordered接口实现优先级控制

三、内置全局过滤器全景解析

SpringCloud Gateway内置了十余个开箱即用的全局过滤器:

3.1 核心过滤器列表

1. LoadBalancerClientFilter(顺序:10100)

public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
    // 服务发现与负载均衡实现
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        URI originalUrl = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
        if (originalUrl != null && "lb".equals(originalUrl.getScheme())) {
            // 执行服务实例选择
            ServiceInstance instance = loadBalancer.choose(serviceId);
            // 重构请求URL
            URI reconstructedUri = reconstructURI(instance, originalUrl);
            exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, reconstructedUri);
        }
        return chain.filter(exchange);
    }
}

2. ForwardRoutingFilter(顺序:2147483647)

3. NettyRoutingFilter(顺序:2147483647)

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    // 获取目标URI
    URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
    
    // 仅处理http/https请求
    if (!"http".equals(requestUrl.getScheme()) && !"https".equals(requestUrl.getScheme())) {
        return chain.filter(exchange);
    }
    
    // 使用Netty HttpClient发送请求
    return gatewayHttpClient.get().request(adaptedRequest).response()
        .doOnNext(res -> {
            // 处理响应头
            exchange.getResponse().getHeaders().putAll(res.headers());
        });
}

4. WebClientHttpRoutingFilter

5. RouteToRequestUrlFilter(顺序:10000)

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
    if (route == null) {
        return chain.filter(exchange);
    }
    // 合并路由URI与原始路径
    URI mergedUrl = UriComponentsBuilder.fromUri(route.getUri())
            .path(exchange.getRequest().getURI().getRawPath())
            .build().toUri();
    exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, mergedUrl);
    return chain.filter(exchange);
}

3.2 辅助型过滤器

  1. AdaptCachedBodyGlobalFilter:缓存请求体用于后续读取
  2. NettyWriteResponseFilter:处理Netty响应写出
  3. ForwardPathFilter:路径标准化处理
  4. GatewayMetricsFilter:集成Micrometer指标收集

四、执行机制深度剖析

4.1 过滤器链构建过程

sequenceDiagram
    participant Client
    participant Gateway
    participant FilterChain
    participant Backend
    
    Client->>Gateway: 发起请求
    Gateway->>FilterChain: 1. 加载所有GlobalFilter
    Note right of FilterChain: 按Order数值排序
    FilterChain->>FilterChain: 2. 依次执行过滤器
    FilterChain->>Backend: 3. 执行最终路由
    Backend->>FilterChain: 返回响应
    FilterChain->>Gateway: 4. 逆向执行后置处理
    Gateway->>Client: 返回最终响应

4.2 关键执行节点

  1. 过滤器排序:通过AnnotationAwareOrderComparator排序
  2. 上下文传递:通过ServerWebExchange共享数据
  3. 异常处理:由DefaultErrorWebExceptionHandler处理

4.3 核心属性传递

属性名 类型 作用
GATEWAY_ROUTE_ATTR Route 当前匹配的路由定义
GATEWAY_REQUEST_URL_ATTR URI 实际请求的目标URI
GATEWAY_ORIGINAL_REQUEST_URL_ATTR URI 原始请求URI

五、自定义全局过滤器实践

5.1 基础实现示例

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (!validateToken(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -100; // 高优先级
    }
}

5.2 生产级过滤器建议

  1. 性能考量

    • 避免在过滤器中阻塞操作
    • 使用ServerWebExchangeUtils.cacheRequestBody处理重复读取
  2. 异常处理

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    return chain.filter(exchange)
            .onErrorResume(e -> {
                exchange.getResponse().setStatusCode(HttpStatus.BAD_GATEWAY);
                return exchange.getResponse().setComplete();
            });
}
  1. 链路追踪集成
exchange.getRequest().mutate()
    .header("X-Trace-ID", MDC.get("traceId"))
    .build();

六、常见问题排查

6.1 过滤器不生效排查清单

  1. 检查是否被@Component扫描到
  2. 确认Order值是否被其他过滤器覆盖
  3. 调试FilteringWebHandler的过滤器加载过程

6.2 性能优化建议

  1. 高频操作过滤器设置更高优先级(更小的Order值)
  2. 使用ExchangeUtils缓存计算结果
  3. 避免在过滤器中创建重量级对象

七、版本演进变化

版本 重要变更
2.2.x 引入WebClientHttpRoutingFilter作为备选路由实现
3.0.x 迁移到Reactor 2020.0.x版本
3.1.x 强化Micrometer指标支持
4.0.x 移除Netty运行时依赖,支持更多HTTP客户端

八、总结

SpringCloud Gateway的全局过滤器机制通过精心设计的责任链模式,配合响应式编程范式,为微服务网关提供了高度灵活的扩展能力。深入理解其内置过滤器的执行原理和实现细节,可以帮助开发者更高效地构建企业级API网关解决方案。建议在实际项目中结合具体需求,合理组合内置过滤器和自定义过滤器,同时注意过滤器执行顺序对系统性能的影响。 “`

该文档共约3500字,采用Markdown格式编写,包含: 1. 层级清晰的章节结构 2. 代码片段与执行流程图 3. 对比表格和属性说明表 4. 版本演进与最佳实践建议 5. 生产环境问题排查指南

推荐阅读:
  1. SpringCloud Gateway之过滤器GatewayFilter有什么用
  2. SpringCloud Gateway自定义filter获取body中的数据为空如何解决

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

gateway globalfilter springcloud

上一篇:PHP表单提交的方法有哪些

下一篇:如何实现服务器应用自动重新启动IIS批处理

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》