Spring Cloud Gateway解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: Gateway( 网关),顾名思义,是出现在系统边界上的一个面向API或应用服务的、串行集中式的强管控服务,这里我们讨论的边界可以基于企业IT系统的边界,当然,可以理解为企业级应用防火墙,其目标主要起到隔离外部访问与内部系统交互的作用。在微服务概念的流行之前,网关就已经诞生了,在面向SOA体系中已经成熟,然而,随着微服务体系的快速发展,更进一步将Gateway推向更高的浪口。与其说网关催生了微服务体系,不如说微服务体系拥抱了网关。

      Gateway( 网关),顾名思义,是出现在系统边界上的一个面向API或应用服务的、串行集中式的强管控服务,这里我们讨论的边界可以基于企业IT系统的边界,当然,可以理解为企业级应用防火墙,其目标主要起到隔离外部访问与内部系统交互的作用。在微服务概念的流行之前,网关就已经诞生了,在面向SOA体系中已经成熟,然而,随着微服务体系的快速发展,更进一步将Gateway推向更高的浪口。与其说网关催生了微服务体系,不如说微服务体系拥抱了网关。

      随着微服务架构概念的提出,API 网关成为了微服务架构的一个标配组件,无时无刻在我们的应用系统架构中起着举足轻重的作用,首先,我们来了解下基于Spring Cloud微服务体系网关的架构图,具体如下所示:

       当我们谈论起网关,这玩意到底有什么用?具备哪些功能?具体我们可以参考以下模型图,具体:

       如上图所示:作为网关,其该具备的最基本的四大功能为:统一接入,流量管控,协议适配转发以及安全防护等。

       基于上述,我们分享了网关的历史以及其具备的基本功能,现在我们了解下在不同语言体系环境下所采用的网关技术,目前市面上或者业务场景落地解决方案中,常见的开源网关大致上按照语言分类有如下几类,具体如下图所示:

      若按照使用范围、成熟度以及落地场景等来划分,目前主流网关技术应用涉及以下4 种:OpenResty、Kong、Zuul/Zuul 2、Spring Cloud Gateway,此外,随着Go语言在微服务领域的快速崛起以及应用,fagongzi API 网关最近也获得不少关注。因作者当前公司主要技术栈为Java,故本文重点以Spring Cloud Gateway网关为主,解析其基本原理以及在业务中的应用。

      在Spring 的早期框架中,我们基本上用的是第一代Zuul,随着Spring 5的出现,Spring Cloud 开始完善其生态,引入多种不同的组件以支撑其在微服务体系领域中的地位。因此,Spring Cloud Gateway应运而生。

    Spring Cloud Gateway 是Spring Cloud 生态全新项目,其基于 Spring 5.0、Spring Boot2.0 和 Project Reactor 等技术开发的网关组件,旨在为微服务架构提供简单、有效和统一的 API 路由管理方式,同时提供安全性、监控/度量和限流,Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul。于是,大家肯定在想,这哥们疯了,Zuul都2代了,还搞Gateway ?有意思吗?答案:当然。主要基于以下几点:

  • 提供更简单、高效的 API 网关。
  • Zuul 1.x 采用 Thread per connection 方式处理请求(每个请求一个线程进行处理),

一旦服务响应慢,线程会被阻塞不释放,存在性能瓶颈。

  • 虽然 Zuul 2.x 是适合高并发的版本,但是在 Zuul 2.x 开源前 Spring 团队启动了

Gateway。

       现在,我们来看下Spring Cloud Gateway的基本配置,具体如下所示,

       pom.xml中的Maven依赖,具体可参考:


<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

       application.yml 配置,具体可参考:


spring:
  cloud:
    gateway:
      routes:
        - id: ${serviceId}
          uri: lb://${serviceName}    # http://localhost:8080/
          predicates:
            - Path= /api/**
          filters:
            - StripPrefix=1
  • id - 路由唯一 ID。
  • uri - 目标服务地址,支持普通 URL 和 lb://${服务名称}(表示从注册中心获取服务的

地址)。

  • predicates - 路由条件,匹配请求 URL 判断是否执行该路由。
  • filters - 过滤规则,包括 pre 和 post 过滤等相关规则。

       除此之外,我们还可以通过Java Bean来进行配置,具体如下所示:


@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("path_route2", r -> r.path("/user/getByUsername")
                        .uri("http://localhost:8201/user/getByUsername"))
                .build();
    }
}

       现在,我们继续了解Spring Cloud Gateway 的基本原理,我们先看下其架构图,具体如下所示:

      基于上述拓扑,我们可以看到:Spring Cloud Gateway 依赖 Spring Boot 和 Spring Webflux 提供的 Netty runtime,启动时 Netty Server 监听指定端口,接受客户端请求。请求处理过程如下图,几个重要组成部分:

      1、路由(Route),网关的基本组件,由 ID、目标 URI、Predicate 集合和 Filter 集合组成。

     2、Predicate,Java 8 引入的函数式接口,提供断言(assert)功能,可以匹配 HTTP 请求中的任何内容,如果 Predicate 集合判断结果是 true,表示请求会由该 Route 进行转发。

     3、Filter,为请求提供前置(pre)和后置(post)过滤。

      现在,我们来了解下其工作流原理,基本的处理流程及架构图如下:

      基于上述处理图,我们可以得知:

      1、Gateway接受客户端请求;

      2、网关处理程序映射确定请求与路由匹配,匹配成功则将其发送到网关Web处理程序;

      3、Web处理程序处理程序通过特定于请求的过滤器链运行请求:请求经过 Filter 过滤器链,执行 pre 处理逻辑,如修改请求头信息等;发出代理请求,请求被转发至下游服务并返回响应。

      4、响应经过 Filter 过滤器链,执行 post 处理逻辑。

      5、向客户端响应应答。

      再此,我们看下Spring Cloud Gateway源码实现,以便能够更清晰地去熟悉其内部具体实现细节,具体如下所示:

       网关初始化,启动注解:@GatewayAutoConfiguration(spring-cloud-gateway

-core#org.springframework.cloud.gateway.config),源码如下:


@Service
public class XXXGatewayFilterFactory extends AbstractGatewayFilterFactory<XXXConfig> {
    @Override
    public GatewayFilter apply(final XXXConfig config) {
        return (((exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // ...
            }));
        }));
    }
    @Data
    public static class XXXConfig {
        private String name;
    }
}

      Spring Cloud Gateway 基于 Spring WebFlux 实现,@GatewayClassPathWarningAutoConfiguration 注解用于用于检查项目是否正确导入 spring-boot-starter-webflux 依赖,而不是错误导入 spring-boot-starter-web 依赖。

     @GatewayLoadBalancerClientAutoConfiguration 初始化 LoadBalancerClientFilter 实现负载均衡。

      @GatewayAutoConfiguration 中实现多个核心 Bean 的初始化。Gateway 的配置参数参考 GatewayProperties.class。其基本组件简要源码实现如下:

      Route,作为Gateway 中最基本的组件之一,表示一个具体的路由信息载体。源码如下所示:


public class Route implements Ordered {
    private final String id;
    private final URI uri;        // 路由指向的目的地 uri
    private final int order;      // 多个 Route 之间的排序,数值越小排序越靠前
    private final AsyncPredicate<ServerWebExchange> predicate;    // 匹配 Route 的条件
    private final List<GatewayFilter> gatewayFilters;              // 应用于 Route 的过滤器
}

      Predicate 组件用于匹配请求和 Route,其总共定义3 种逻辑操作方法:and/or/negate。源码如下所示:


public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {
    default AsyncPredicate<T> and(AsyncPredicate<? super T> other) {
        // 两个 Predicate 同时满足
    }
    default AsyncPredicate<T> negate() {
        // 对 Predicate 匹配结果取反
    }
    default AsyncPredicate<T> or(AsyncPredicate<? super T> other) {
        // 两个 Predicate 只需满足其一
    }
}

      Filter 组件功能主要用于请求代理之前或之后,最终通过 filter chain 形成链式进行调用,每个filter处理完pre filter逻辑后委派给 filter chain,其再委派给下一个filter。具体源码如下:


public interface GatewayFilter extends ShortcutConfigurable {
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
public interface GatewayFilterChain {
    Mono<Void> filter(ServerWebExchange exchange);
}

      接下来,我们再看下RouteLocator,其主要用于获取 Route,通过 RouteDefinitionLocator 获取到 RouteDefinition,然后转换成Route,源码如下所示:


public interface RouteLocator {
    Flux<Route> getRoutes();
}
public class RouteDefinitionRouteLocator implements RouteLocator, 
        BeanFactoryAware, ApplicationEventPublisherAware {
    private final RouteDefinitionLocator routeDefinitionLocator;
    // RoutePredicateFactory 列表
    private final Map<String, RoutePredicateFactory> predicates = new LinkedHashMap();
    // GatewayFilterFactory 列表
    private final Map<String, GatewayFilterFactory> gatewayFilterFactories = new HashMap();
    public Flux<Route> getRoutes() {
        return this.routeDefinitionLocator.getRouteDefinitions()
                .map(this::convertToRoute)
                .map((route) -> {
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("RouteDefinition matched: " + route.getId());
                    }
                    return route;
                });
    }
    private Route convertToRoute(RouteDefinition routeDefinition) {
        AsyncPredicate<ServerWebExchange> predicate = this.combinePredicates(routeDefinition);
        List<GatewayFilter> gatewayFilters = this.getFilters(routeDefinition);
        return ((AsyncBuilder)Route
                    .async(routeDefinition)
                    .asyncPredicate(predicate)
                    .replaceFilters(gatewayFilters))
                .build();
    }
}

     路由匹配部分,Spring WebFlux 的访问入口 org.springframework.web.reactive.DispatcherHandler(对应 MVC 中的 DispatcherServlet),具体源码可参考如下:


public class DispatcherHandler implements WebHandler, ApplicationContextAware {
    private List<HandlerMapping> handlerMappings;
    private List<HandlerAdapter> handlerAdapters;
    public Mono<Void> handle(ServerWebExchange exchange) {
        // 顺序使用 handlerMappings 获得对应的 WebHandler,invoke 执行
        return Flux.fromIterable(this.handlerMappings)
            // RoutePredicateHandlerMapping
            .concatMap((mapping) -> { return mapping.getHandler(exchange); })
            .next()
            .switchIfEmpty(this.createNotFoundError())
            // SimpleHandlerAdapter
            .flatMap((handler) -> { return this.invokeHandler(exchange, handler); })
            .flatMap((result) -> { return this.handleResult(exchange, result); });
    }
}

      RoutePredicateHandlerMapping 匹配路由,源码如下:


public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
    private final FilteringWebHandler webHandler;
    private final RouteLocator routeLocator;
    // mapping.getHandler(exchange); 会调用至此
    protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
        return this.lookupRoute(exchange)    // 匹配 Route
            .flatMap((r) -> {
                // ...
                return Mono.just(this.webHandler);
            })
            .switchIfEmpty(/**未匹配到 Route**/);
    }
}

      最后,我们在了解下Filter chain,SimpleHandlerAdapter 循环执行 WebHandler,我们以 FilteringWebHandler 为例,创建 GatewayFilterChain 处理请求,具体源码如下:


public class SimpleHandlerAdapter implements HandlerAdapter {
    public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
        WebHandler webHandler = (WebHandler)handler;
        Mono<Void> mono = webHandler.handle(exchange);
        return mono.then(Mono.empty());
    }
}
public class FilteringWebHandler implements WebHandler {
    public Mono<Void> handle(ServerWebExchange exchange) {
        Route route = (Route)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
        List<GatewayFilter> gatewayFilters = route.getFilters();
        List<GatewayFilter> combined = new ArrayList(this.globalFilters);
        // 合并 GlobalFilter 和 GatewayFilter,整体排序
        combined.addAll(gatewayFilters);
        AnnotationAwareOrderComparator.sort(combined);
        // 创建 GatewayFilterChain 处理请求
        return (new FilteringWebHandler.DefaultGatewayFilterChain(combined))
          .filter(exchange);
    }
}

      至此,Spring Cloud Gateway基本解析到此为止,大家有什么问题或者建议,欢迎随时留言沟通。

相关文章
|
10天前
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
|
21天前
|
XML Java 开发者
Spring底层架构核心概念解析
理解 Spring 框架的核心概念对于开发和维护 Spring 应用程序至关重要。IOC 和 AOP 是其两个关键特性,通过依赖注入和面向切面编程实现了高效的模块化和松耦合设计。Spring 容器管理着 Beans 的生命周期和配置,而核心模块为各种应用场景提供了丰富的功能支持。通过全面掌握这些核心概念,开发者可以更加高效地利用 Spring 框架开发企业级应用。
74 18
|
1月前
|
存储 弹性计算 安全
Cloud Backup深度解析:从被动防御到主动保护
《Cloud Backup深度解析:从被动防御到主动保护》由阿里云高级技术专家张磊分享,探讨企业数据保护面临的挑战及应对策略。内容涵盖企业数据安全威胁、小概率事件的高风险性、传统备份系统的不足,以及通过四步主动防御策略(资源发现、风险检测、数据锁定、全局巡检)实现高效的数据保护。同时介绍了基于标签的自动策略关联、多种备份引擎、恶意文件检测、探测效率优化等关键技术,确保备份数据的安全性和完整性。此外,还展示了数据灾备中心和全方位主动数据保护机制,帮助企业在面对勒索病毒、内部攻击等威胁时,构建更强大的防护体系。
|
2月前
|
JSON Java API
利用Spring Cloud Gateway Predicate优化微服务路由策略
Spring Cloud Gateway 的路由配置中,`predicates`​(断言)用于定义哪些请求应该匹配特定的路由规则。 断言是Gateway在进行路由时,根据具体的请求信息如请求路径、请求方法、请求参数等进行匹配的规则。当一个请求的信息符合断言设置的条件时,Gateway就会将该请求路由到对应的服务上。
185 69
利用Spring Cloud Gateway Predicate优化微服务路由策略
|
2月前
|
存储 SpringCloudAlibaba Java
【SpringCloud Alibaba系列】一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论
一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论。
【SpringCloud Alibaba系列】一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论
|
2月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
2月前
|
JavaScript Java Kotlin
深入 Spring Cloud Gateway 过滤器
Spring Cloud Gateway 是新一代微服务网关框架,支持多种过滤器实现。本文详解了 `GlobalFilter`、`GatewayFilter` 和 `AbstractGatewayFilterFactory` 三种过滤器的实现方式及其应用场景,帮助开发者高效利用这些工具进行网关开发。
362 1
|
3月前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
234 2
|
1月前
|
人工智能 安全 Java
AI 时代:从 Spring Cloud Alibaba 到 Spring AI Alibaba
本次分享由阿里云智能集团云原生微服务技术负责人李艳林主讲,主题为“AI时代:从Spring Cloud Alibaba到Spring AI Alibaba”。内容涵盖应用架构演进、AI agent框架发展趋势及Spring AI Alibaba的重磅发布。分享介绍了AI原生架构与传统架构的融合,强调了API优先、事件驱动和AI运维的重要性。同时,详细解析了Spring AI Alibaba的三层抽象设计,包括模型支持、工作流智能体编排及生产可用性构建能力,确保安全合规、高效部署与可观测性。最后,结合实际案例展示了如何利用私域数据优化AI应用,提升业务价值。
140 4
|
1月前
|
人工智能 自然语言处理 Java
Spring Cloud Alibaba AI 入门与实践
本文将介绍 Spring Cloud Alibaba AI 的基本概念、主要特性和功能,并演示如何完成一个在线聊天和在线画图的 AI 应用。
357 7

推荐镜像

更多