文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

细到不能再细的 Spring Cloud Gateway 原理分析(内含多张图片讲解)

2023-09-07 18:25

关注

前言

本文会通过图文的方式由浅入深的描述 Spring Cloud Gateway (以下简称 gateway)的基本原理。

本文不涉及 gateway 的任何示例代码, 如有需要请参考官网 sample

阅读前, 需要读者提前掌握 gateway 的基本使用。至少要能读懂如下配置的含义:

spring:  cloud:    gateway:      routes:      - id: test_route        uri: lb://service-A        predicates:         - Path=/hello        filters:        - SetRequestHeader=X-Request-Red, Blue

正文

一、Gateway 在微服务中的作用

在这里插入图片描述

  1. 请求方 发送一个请求到达 gateway 时,gateway 根据 配置的路由规则,找到 对应的服务名称
  2. 当某个服务存在多个实例时,gateway 会根据 负载均衡算法(比如:轮询)从中挑选出一个实例,然后将请求 转发 过去。
  3. 服务实例返回的的响应结果会再经过 gateway 转发给请求方。

以上便是 gateway 最基本的作用,它处理请求是逻辑是根据 配置的路由 对请求进行 预处理转发

除此之外,还包括但不限于如下功能:

以上功能皆非本文讨论的重点内容,仅在此提及一下。

二、Gateway 的工作原理

在讨论 gateway 工作原理之前, 我们先思考下, 如果让我们制作一个简单的网关应用, 实现方式有哪些。

2.1 实现一个网关的几种方式

根据上一章节末的描述可知, gateway 主要用于请求的转发处理。因此这里就涉及了网络通信的知识。

2.1.1 基于 socket API 实现

在这里插入图片描述

2.1.2 基于 Netty 实现

在这里插入图片描述

2.1.3 基于 Web 框架

在这里插入图片描述

2.2 gateway 的底层实现原理

先简单翻译一下摘自 gateway 官网的描述:

SpringCloud Gateway 是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关。为了提升网关的性能,SpringCloud Gateway 是基于 WebFlux 框架实现的,而 WebFlux 框架底层则使用了高性能的 Reactor 模式通信框架 Netty。

然后我们结合 2.1 章节的分析, 可以将官网的描述成如下大白话:

  1. 实现网关必将涉及到网络通信,众所周知 Netty 是一款 出色 的网络通信框架。
  2. 为了提升网关的性能, gateway 使用到了响应式编程。
  3. 而 WebFlux 框架底层就使用了高性能的 Reactor 模式通信框架 Netty,所以可以直接拿来用。

PS: 至于什么是响应式编程, 为什么 gateway 基于这些技术能够实现高性能, 这些不是本文探讨的内容,感兴趣的读者可以自行去了解。

那么, 如何理解 Spring WebFlux,我们暂且就把它当做 Spring WebMVC。一个 web 框架。
他们之间很重要的一个区别就在于 webmvc 我们一般会基于 tomcat 容器去完成底层的网络通信, 而 webflux 是基于 Netty

2.3 gateway 是如何工作的

我们先来看下官网的描述:
在这里插入图片描述

  1. 客户端向 Spring Cloud Gateway 发出请求。
  2. 如果 Gateway Handler Mapping 找到与请求相匹配的路由,将其发送到 Gateway Web Handler。
  3. Handler 再通过指定的 过滤器链 来将请求发送到我们实际的服务执行业务逻辑,然后返回。
  4. 过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

从图中可以看出, 在 gateway 视角里,它在处理请求时, 划分成如下三大角色:

此时, 如果熟悉 Spring MVC 工作原理的可以看出,它和 Springmvc 的核心工作流程是类似的。

2.4 webflux 的工作原理以及 gateway 是如何基于它进行扩展

上面说到, gateway 底层还是基于 webflux。我们首先简单了解下 webflux 的工作原理, 然后延伸到 gateway 是如何基于 webflux 做扩展的。

在这里插入图片描述

以上是 webflux 处理请求的代码链路。我们着重看下标有颜色的类。

  1. 接受请求的关键类是 ReactorHttpHandlerAdapter,他的作用是将 netty 的请求、响应转为 http 的请求、响应, 并交给后面的类处理。
  2. 标记 ① 位置的过滤器链是 webflux 自身的。
  3. 标记 ③ 对应的 FilteringWebHandler 是 gateway 对 webflux 的扩展。
  4. 标记 ②③④ 整理对应最上面的 gateway 的工作流程。

简单总结:

  1. webflux 在处理请求时,会先执行自身的过滤器链
  2. 然后通过 HandlerMapping 拿到对应的 Handller
  3. gateway 通过 第二步 webflux 提供的扩展点, 实现了对应的接口, 最终导致 代码链路 走到了 gateway 中定义的 Handler, 此时 gateway 就可以对到来的请求 “为所欲为” 了。
  4. gateway 通过定义自己的过滤器链,从而又方便了开发者对其进行自定义扩展。

如果没看懂, 可以看完下面的内容, 再回过头来看本章节。

三、Gateway 的核心组件

Gateway 有三个比较核心的组件, 可以结合如下路由配置看一看:

spring:  cloud:    gateway:      routes:      - id: test_route        uri: lb://service-A        predicates:         - Path=/hello        filters:        - SetRequestHeader=X-Request-Red, Blue

围绕上述三个组件, gateway 又衍生出了一些其他组件。

具体作用我们会在下面一一说明。
在这里插入图片描述

接下来,我们通过对上图进行讲解, 来详细介绍各个组件在 gateway 中的作用。

首先, gateway 本质就是一个 Springboot 应用, 他是通过 webflux 框架处理请求和响应,而 webflux 底层是基于 Netty

四、gateway 的更多细节

4.1 RouteDefinition 和 Route

RouteDefinition 定义了一个路由应该包含哪些匹配条件和过滤器,以及这些匹配条件和过滤器使用的参数, 它表示的是一个名词定义。在使用时 Gateway进行路由时, 会根据 RouteDefinition 对象提供的定义构造出 Route 对象,而 Route 里面提供了很多动作。

并且我们在前面提到: “一个 Route 可以包含多个 Predicates,多个 Predicates 最终会合并成一个。因此我们可以看到,关于 Predicates,RouteDefinition 里面定义的是一个集合, 而 Route 中只是一个对象。

public class RouteDefinition {// ...private List<PredicateDefinition> predicates = new ArrayList<>();}
public class Route implements Ordered {// ....private final AsyncPredicate<ServerWebExchange> predicate;}

4.2 RouteLocator

RouteLocator 接口中定义了获取路由配置的方法,RouteLocator 有不同的实现,对应了不同的定义路由的方式。

public interface RouteLocator {Flux<Route> getRoutes();}

前文中我们提到,定义路由的其中一个方式是通过 RouteLocatorBuilder 提供的 API 来构建具体的 Route

如下代码中定义了一个路由,其中包含了一个 path 匹配条件,以及一个添加响应 header 的 filter,请求转发的目标地址是 https://blog.csdn.net

@Beanpublic RouteLocator routeLocator(RouteLocatorBuilder builder) {  return builder.routes()    .route("route-id", r -> r.path("/test").filters(f -> f.addResponseHeader("X-TestHeader", "foobar")).uri("https://blog.csdn.net"))    .build();}

RouteDefinitionRouteLocatorRouteLocator 另一种常用的实现 。这种实现依赖于 RouteDefinitionLocator 来提供 RouteDefinition ,再由 RouteDefinition 构造路由。

CompositeRouteLocator 会把所有的 RouteLocator 的实现组合起来,再缓存到 CachingRouteLocator 中 。

因此当我们调用 getRoutes 方法获取路由集合时, 就会产生如下的调用关系:

在这里插入图片描述

4.3 RouteDefinitionLocator

RouteDefinitionLocator 接口定义了获取 RouteDefinition 的方法。

public interface RouteDefinitionLocator {Flux<RouteDefinition> getRouteDefinitions();}

前面我们多次提到 PropertiesRouteDefinitionLocator 可以通过解析 gateway 的配置文件中的路由配置拿到 RouteDefinition 对象集合

同上面的 RouteLocator 一样, 当 gateway 中有多个 RouteDefinitionLocator 实现时 , 同样会被 CompositeRouteDefinitionLocator 组合起来。

4.4 Filter

gateway 处理请求和响应的核心逻辑就在 Filter 中。gateway 本身实现提供了基础通用的过滤器,可以直接配置使用。 比如在请求前后, 分别添加请求头和响应头
我们再来看几个比较有意思的全局过滤器:

总结

本文通过图文结合的方式, 介绍了 Spring Cloud Gateway 的基本工作原理。

另外,本文的不足之处包括但不限于如下几点:

  1. 没有详细说明 Spring Cloud Gateway 高性能的原因是什么。
  2. 没有对 gateway 如何实现用户鉴权、灰度发布等功能进行说明。
  3. 没有足够的源码分析。
  4. 没有说明如何对 gateway 进行扩展实现。

当然, 后面如果有条件会对以上几点进行补充说明。

来源地址:https://blog.csdn.net/cnm10050/article/details/127261680

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯