热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

详解SpringCloudGateway之过滤器GatewayFilter

这篇文章主要介绍了详解SpringCloudGateway之过滤器GatewayFilter,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

在Spring-Cloud-Gateway之请求处理流程文中我们了解最终网关是将请求交给过滤器链表进行处理,接下来我们阅读Spring-Cloud-Gateway的整个过滤器类结构以及主要功能

通过源码可以看到Spring-Cloud-Gateway的filter包中吉接口有如下三个,GatewayFilter,GlobalFilter,GatewayFilterChain,下来我依次阅读接口的主要实现功能。

GatewayFilterChain

类图


代码

/**
 * 网关过滤链表接口
 * 用于过滤器的链式调用
 * Contract to allow a {@link WebFilter} to delegate to the next in the chain.
 *
 * @author Rossen Stoyanchev
 * @since 5.0
 */
public interface GatewayFilterChain {

  /**
   * 链表启动调用入口方法
   * Delegate to the next {@code WebFilter} in the chain.
   * @param exchange the current server exchange
   * @return {@code Mono} to indicate when request handling is complete
   */
  Mono filter(ServerWebExchange exchange);

}
  /**
   * 网关过滤的链表,用于过滤器的链式调用
   * 过滤器链表接口的默认实现,
   * 包含2个构建函数:
   * 1.集合参数构建用于初始化吧构建链表
   * 2. index,parent参数用于构建当前执行过滤对应的下次执行的链表 
   */
  private static class DefaultGatewayFilterChain implements GatewayFilterChain {

    /**
     * 当前过滤执行过滤器在集合中索引
     */
    private final int index;
    /**
     * 过滤器集合
     */
    private final List filters;

    public DefaultGatewayFilterChain(List filters) {
      this.filters = filters;
      this.index = 0;
    }

    /**
     * 构建
     * @param parent 上一个执行过滤器对应的FilterChain
     * @param index 当前要执行过滤器的索引
     */
    private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
      this.filters = parent.getFilters();
      this.index = index;
    }

    public List getFilters() {
      return filters;
    }

    /**
     * @param exchange the current server exchange
     * @return
     */
    @Override
    public Mono filter(ServerWebExchange exchange) {
      return Mono.defer(() -> {
        if (this.index 

过滤器的GatewayFilterChain 执行顺序

  1. 通过GatewayFilter集合构建顶层的GatewayFilterChain
  2. 调用顶层GatewayFilterChain,获取第一个Filter,并创建下一个Filter索引对应的GatewayFilterChain
  3. 调用filter的filter方法执行当前filter,并将下次要执行的filter对应GatewayFilterChain传入。

GatewayFilter

类图

/**
 * 网关路由过滤器,
 * Contract for interception-style, chained processing of Web requests that may
 * be used to implement cross-cutting, application-agnostic requirements such
 * as security, timeouts, and others. Specific to a Gateway
 *
 * Copied from WebFilter
 *
 * @author Rossen Stoyanchev
 * @since 5.0
 */
public interface GatewayFilter extends ShortcutConfigurable {

  String NAME_KEY = "name";
  String VALUE_KEY = "value";

  /**
   * 过滤器执行方法
   * Process the Web request and (optionally) delegate to the next
   * {@code WebFilter} through the given {@link GatewayFilterChain}.
   * @param exchange the current server exchange
   * @param chain provides a way to delegate to the next filter
   * @return {@code Mono} to indicate when request processing is complete
   */
  Mono filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

网关过滤器接口,有且只有一个方法filter,执行当前过滤器,并在此方法中决定过滤器链表是否继续往下执行,接下来我们看下几个主要的功能实现类

OrderedGatewayFilter

/**
 * 排序的网关路由过滤器,用于包装真实的网关过滤器,已达到过滤器可排序
 * @author Spencer Gibb
 */
public class OrderedGatewayFilter implements GatewayFilter, Ordered {

  //目标过滤器
  private final GatewayFilter delegate;
  //排序字段
  private final int order;

  public OrderedGatewayFilter(GatewayFilter delegate, int order) {
    this.delegate = delegate;
    this.order = order;
  }

  @Override
  public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    return this.delegate.filter(exchange, chain);
  }
}  

OrderedGatewayFilter实现类主要目的是为了将目标过滤器包装成可排序的对象类型。是目标过滤器的包装类

GatewayFilterAdapter

  /**
   * 全局过滤器的包装类,将全局路由包装成统一的网关过滤器
   */
  private static class GatewayFilterAdapter implements GatewayFilter {

    /**
     * 全局过滤器
     */
    private final GlobalFilter delegate;

    public GatewayFilterAdapter(GlobalFilter delegate) {
      this.delegate = delegate;
    }

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      return this.delegate.filter(exchange, chain);
    }
  }

GatewayFilterAdapter实现类主要目的是为了将GlobalFilter过滤器包装成GatewayFilter类型的对应。是GlobalFilter过滤器的包装类

GlobalFilter

GlobalFilter 为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,模式系统初始化时加载,并作用在每个路由上。

初始化加载,通过GatewayAutoConfiguration自动创建

GatewayAutoConfiguration 类

    /**
     * 全局过滤器,用户通过HttpClient转发请求
     * @param httpClient
     * @param headersFilters
     * @return
     */
    @Bean
    public NettyRoutingFilter routingFilter(HttpClient httpClient,
                        ObjectProvider> headersFilters) {
      return new NettyRoutingFilter(httpClient, headersFilters);
    }

    /**
     * 全局的过滤器,用户将HttpClient客户端转发请求的响应写入到原始的请求响应中
     * @param properties
     * @return
     */
    @Bean
    public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {
      return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());
    }

GatewayLoadBalancerClientAutoConfiguration 类

  /**
   * 全局过滤器,用于在通过负载均衡客户端选择服务实例信息
   * @param client
   * @return
   */
  @Bean
  @ConditionalOnBean(LoadBalancerClient.class)
  public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
    return new LoadBalancerClientFilter(client);
  }

GlobalFilter转换成GatewayFilter,并作用于每个路由上,在FilteringWebHandler实现

FilteringWebHandler类

  /**
   * 包装加载全局的过滤器,将全局过滤器包装成GatewayFilter
   * @param filters
   * @return
   */
  private static List loadFilters(List filters) {
    return filters.stream()
        .map(filter -> {
          //将所有的全局过滤器包装成网关过滤器
          GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
          //判断全局过滤器是否实现了可排序接口
          if (filter instanceof Ordered) {
            int order = ((Ordered) filter).getOrder();
            //包装成可排序的网关过滤器
            return new OrderedGatewayFilter(gatewayFilter, order);
          }
          return gatewayFilter;
        }).collect(Collectors.toList());
  }
  @Override
  public Mono handle(ServerWebExchange exchange) {
    //获取请求上下文设置的路由实例
    Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
    //获取路由定义下的网关过滤器集合
    List gatewayFilters = route.getFilters();

    //组合全局的过滤器与路由配置的过滤器
    List combined = new ArrayList<>(this.globalFilters);
    //添加路由配置过滤器到集合尾部
    combined.addAll(gatewayFilters);
    //对过滤器进行排序
    //TODO: needed or cached&#63;
    AnnotationAwareOrderComparator.sort(combined);

    logger.debug("Sorted gatewayFilterFactories: "+ combined);
    //创建过滤器链表对其进行链式调用
    return new DefaultGatewayFilterChain(combined).filter(exchange);
  }

loadFilters方法是将全局路由使用GatewayFilterAdapter包装成GatewayFilter

handle方法

  • 获取当前请求使用的路由Route
  • 获取路由配置的过滤器集合route.getFilters()
  • 合并全过滤器与路由配置过滤器combined
  • 对过滤器排序AnnotationAwareOrderComparator.sort
  • 通过过滤器集合构建顶级链表DefaultGatewayFilterChain,并对其当前请求调用链表的filter方法。

==备注==:

Spring-Cloud-Gateway的过滤器接口分为两种:

  • GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器
  • GatewayFilter : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上

至此,网关过滤器的整个结构以及加载使用流程源码已经阅读完毕,下篇重点学习下路由配置的过滤器加载创建流程

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 一面问题:MySQLRedisKafka线程算法mysql知道哪些存储引擎,它们的区别mysql索引在什么情况下会失效mysql在项目中的优化场景&# ... [详细]
  • 本文详细介绍了 Nginx 中用于端口监听的核心配置指令,包括其基本用法和高级选项。 ... [详细]
  • 本文详细探讨了在Windows Server 2003环境下遇到MySQL连接失败(错误代码10061)的解决方案,包括通过卸载特定的Windows更新和调整系统注册表设置的方法。 ... [详细]
  • ipvsadm命令简介:ipvsadm是LVS在应用层的管理命令,我们可以通过这个命令去管理LVS的配置。在fedora14、Linux6.0之后系统中 ... [详细]
  • 本文档详细介绍了服务器与应用系统迁移的策略与实施步骤。迁移不仅涉及数据的转移,还包括环境配置、应用兼容性测试等多个方面,旨在确保迁移过程的顺利进行及迁移后的系统稳定运行。 ... [详细]
  • Linux双网卡绑定技术详解与实践
    本文详细介绍了如何在Linux系统中实现双网卡绑定,即将两块物理网卡合并为一个逻辑网卡,以提高网络性能和可靠性。文中不仅涵盖了基本的概念,还提供了具体的配置步骤和测试方法。 ... [详细]
  • 本文详细介绍了RocketMQ中的消息并发消费机制,包括消息拉取后的处理流程、消费服务的调用以及消费任务的具体执行过程。 ... [详细]
  • MHA 架构详解与实践
    MHA(Master High Availability)是一种高效的主从切换解决方案,确保了数据的一致性和系统的高可用性。本文将详细介绍MHA的功能、主从切换流程以及配置步骤,并探讨其优缺点。 ... [详细]
  • 深入解析ZooKeeper:Java组件化开发必备技能
    本文详细介绍了ZooKeeper作为分布式服务协调框架的核心功能与应用场景,包括其数据一致性解决方案、数据结构特点、监听通知机制及选举机制等,帮助开发者更好地理解和应用ZooKeeper。 ... [详细]
  • 网络层详解——湖南科技大学《计算机网络微课堂》笔记4.1
    本文详细介绍了网络层的主要路由协议,包括RIP、OSPF、BGP的工作原理及其特点,并探讨了IPv4数据报的首部格式、ICMP协议以及虚拟专用网(VPN)和网络地址转换(NAT)的相关知识。 ... [详细]
  • 微服务架构详解及其入门指南
    本文详细介绍了微服务的基本概念、发展历程、与传统架构的区别及优势,并探讨了适合采用微服务架构的场景。此外,文章还深入分析了几个主流的微服务开发框架,特别是Spring Cloud的组成和特点。 ... [详细]
  • 应对高并发面试题:构建稳健的系统架构策略
    本文探讨了如何在面试中有效地回答有关高并发系统设计的问题。通过逐步介绍从单机部署到集群化、数据库优化、缓存应用及消息队列的使用,帮助读者建立解决高并发挑战的基本思路。 ... [详细]
  • 2020年腾讯PCG后端开发实习生面试经历分享
    本文详细记录了2020年腾讯平台与内容事业群(PCG)后端开发实习生岗位的面试过程,包括初试和复试的主要内容和技术考察点。 ... [详细]
  • Spring Boot 初学者指南(第一部分)
    本文介绍了Spring Boot框架的基础知识,包括其设计理念、主要优势以及如何简化传统的J2EE开发流程。 ... [详细]
  • 本文详细探讨了 HAProxy 的基本概念及其与 LVS(Linux Virtual Server)的比较,特别是在内核空间与用户空间的工作差异。文章还深入介绍了 HAProxy 独有的数据结构——弹性二叉树,以及其在高并发场景下的表现。 ... [详细]
author-avatar
啊健oo
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有