Soul API 网关源码学习《一》

Soul API 网关源码解析 01

一、初识网关

“网关”一个对开发人员众所周知的词语,那么什么是网关呢?在维基百科中的定义是:“网关是程序或者系统之间的连接点,扮演者程序和系统之间的门户,允许它们之间通过通讯协议交换信息,它们可能是同构和异构的系统”。

其实,简而言之网关就是一种外部网络和内部服务之间的关卡,它可以最先得到外部的请求。当然从软硬件角度来看,网关可分为软件网关硬件网关,硬件网关也就是我们所熟知的 LVS 和 F5,但是一般来说这不是我们所需要了解的,软件网关则有:Nginx、CGI、KONG、Zuul、Gateway、Soul。

本文章所要介绍的是 Soul 网关,但是在正式说 Soul 之前,简单说一下 Zuul 和 Gateway。因为接触过 Spring Cloud 的童鞋,应该说都有接触过的,而 Spring Cloud 抛弃 Zuul,也是有一定原因的。

1.关于 Zuul

首先来看看 Zull 的执行方式,如图:

图片

Zuul 网关的原理上,是会为一个请求分配一条线程,然后通过执行不同类型的过滤器来完成路由的工作,但是这条线程会等 route 类型的过滤器去调用源服务器,从上图中可以看出这里线程执行的时间会比较长,因为源服务器的业务可能很复杂,而导致响应比较慢,所以这会导致 Zuul 的线程执行的时间比较长,也就会造成线程积压,以至于性能变慢。这也是 Gateway 产生的原因(还有 Zuul 2.x 迟迟不能出生)。

Zuul 提供的功能有:

  • 身份验证
  • 检验和安全
  • 限流
  • 动态路由
  • 压力测试
  • 静态响应处理
  • 多区域弹性

2.关于 Gateway

如上,我们依然先看看 Gateway 的执行方式,如图:

图片

Gateway 处理步骤:

  1. 创建一条线程通过类似 Zuul 的过滤器拦截请求;
  2. 对源服务器转发请求,注意这里 Gateway 并不会等待请求调用源服务器的过程,而是将处理线程挂起,以此来不占用资源;
  3. 等源服务器返回消息后,再通过寻址的方式来响应之前客户发送的请求;

从上面的执行流程中,可以知道 Gateway 处理请求的时候,只是负责转发请求至源服务器,并不会等待请求完成,而请求源服务器正是比较慢的一个环节,因此 Gateway 的线程活动时间比较短,线程积压概率也降低了,这也是性能高于 Zuul 的原因。

再简单介绍了 Zuul 和 Gateway 两种网关之后,我们正式来到我们对 Soul 网关的认识了,其实介绍 Gateway 的原因之一,也是因为 Soul 是参考了 Kong、Spring Cloud Gateway等优秀的网关后,站在巨人的肩膀上,Soul 便由此诞生。

二、Soul 网关简介

Soul是基于WebFlux实现的响应式的 API 网关,具有异步、高性能、跨语言等特点。

soul 架构如下图所示:

图片

Soul 核心(Feature):

  • 支持各种语言(http 协议),支持 dubbo,springcloud 协议。
  • 插件化设计思想,插件热插拔,易扩展。
  • 灵活的流量筛选,能满足各种流量控制。
  • 内置丰富的插件支持,鉴权,限流,熔断,防火墙等等。
  • 流量配置动态化,性能极高,网关消耗在 1~2ms。
  • 支持集群部署,支持 A/B Test, 蓝绿发布。

三、Soul 开发环境搭建

在简单的介绍了 Soul 之后,我们便正式进入源码构建 的环节了,大家都知道学习一个框架的第一步就是构建源码,那我们就正式开始吧!(注:笔者 jdk 依赖于 jdk1.8 版本)

1、git clone 源码

拉取源码可以先 fork 到自己的 git 仓库中,也可以直接 clone 下来,这里笔者就直接 clone 了。

git clone https://github.com/dromara/soul.git

执行结果如下:
图片

2、编译代码

当代码拉取完成后,便可以进行编译啦,先进入到代码的目录,然后再执行编译命令。这里使用的编译工具是 maven,关于 maven 命令可自行在网上搜索学习资料。编译命令如下:

mvn clean package install -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -Drat.skip=true -Dcheckstyle.skip=true

编译结果:

ElishadeMacBook-Pro:IdeaProject alisha$ cd soul/
ElishadeMacBook-Pro:soul alisha$ mvn clean package install -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -Drat.skip=true -Dcheckstyle.skip=true
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] soul                                                               [pom]
......................中间省略一万步......................
trap-dist-2.2.1.tar.gz
[INFO] Installing /Users/alisha/IdeaProject/soul/soul-dist/soul-bootstrap-dist/target/soul-bootstrap-bin-2.2.1.tar.gz to /Users/alisha/java/MavenRepository/org/dromara/soul-bootstrap-dist/2.2.1/soul-bootstrap-dist-2.2.1.tar.gz
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for soul 2.2.1:
[INFO]
[INFO] soul ............................................... SUCCESS [  3.397 s]
[INFO] soul-common ........................................ SUCCESS [  4.791 s]
[INFO] soul-admin ......................................... SUCCESS [  8.844 s]
[INFO] soul-plugin ........................................ SUCCESS [  0.031 s]
[INFO] soul-plugin-api .................................... SUCCESS [  0.907 s]
[INFO] soul-sync-data-center .............................. SUCCESS [  0.040 s]
[INFO] soul-sync-data-api ................................. SUCCESS [  0.779 s]
[INFO] soul-plugin-global ................................. SUCCESS [  0.857 s]
[INFO] soul-spring-boot-starter ........................... SUCCESS [  0.032 s]
[INFO] soul-spring-boot-starter-plugin .................... SUCCESS [  0.028 s]
[INFO] soul-spring-boot-starter-plugin-global ............. SUCCESS [  1.284 s]
[INFO] soul-spi ........................................... SUCCESS [  0.703 s]
[INFO] soul-plugin-base ................................... SUCCESS [  1.072 s]
[INFO] soul-metrics ....................................... SUCCESS [  0.033 s]
[INFO] soul-metrics-spi ................................... SUCCESS [  0.893 s]
[INFO] soul-metrics-prometheus ............................ SUCCESS [  1.104 s]
[INFO] soul-metrics-facade ................................ SUCCESS [  0.790 s]
[INFO] soul-web ........................................... SUCCESS [  1.298 s]
[INFO] soul-spring-boot-starter-gateway ................... SUCCESS [  0.043 s]
[INFO] soul-plugin-divide ................................. SUCCESS [  0.972 s]
[INFO] soul-spring-boot-starter-plugin-divide ............. SUCCESS [  0.663 s]
[INFO] soul-plugin-alibaba-dubbo .......................... SUCCESS [  0.967 s]
[INFO] soul-spring-boot-starter-plugin-alibaba-dubbo ...... SUCCESS [  0.802 s]
[INFO] soul-plugin-apache-dubbo ........................... SUCCESS [  0.980 s]
[INFO] soul-spring-boot-starter-plugin-apache-dubbo ....... SUCCESS [  0.695 s]
[INFO] soul-plugin-httpclient ............................. SUCCESS [  1.097 s]
[INFO] soul-spring-boot-starter-plugin-httpclient ......... SUCCESS [  0.841 s]
[INFO] soul-plugin-springcloud ............................ SUCCESS [  0.690 s]
[INFO] soul-spring-boot-starter-plugin-springcloud ........ SUCCESS [  0.819 s]
[INFO] soul-plugin-hystrix ................................ SUCCESS [  0.869 s]
[INFO] soul-spring-boot-starter-plugin-hystrix ............ SUCCESS [  0.712 s]
[INFO] soul-plugin-monitor ................................ SUCCESS [  0.634 s]
[INFO] soul-spring-boot-starter-plugin-monitor ............ SUCCESS [  0.641 s]
[INFO] soul-plugin-ratelimiter ............................ SUCCESS [  1.063 s]
[INFO] soul-spring-boot-starter-plugin-ratelimiter ........ SUCCESS [  0.675 s]
[INFO] soul-plugin-sign ................................... SUCCESS [  0.747 s]
[INFO] soul-spring-boot-starter-plugin-sign ............... SUCCESS [  0.665 s]
[INFO] soul-plugin-waf .................................... SUCCESS [  0.777 s]
[INFO] soul-spring-boot-starter-plugin-waf ................ SUCCESS [  0.622 s]
[INFO] soul-plugin-rewrite ................................ SUCCESS [  0.646 s]
[INFO] soul-spring-boot-starter-plugin-rewrite ............ SUCCESS [  0.872 s]
[INFO] soul-plugin-sentinel ............................... SUCCESS [  0.748 s]
[INFO] soul-spring-boot-starter-plugin-sentinel ........... SUCCESS [  0.730 s]
[INFO] soul-plugin-sofa ................................... SUCCESS [  7.389 s]
[INFO] soul-spring-boot-starter-plugin-sofa ............... SUCCESS [  0.731 s]
[INFO] soul-plugin-resilience4j ........................... SUCCESS [  0.896 s]
[INFO] soul-spring-boot-starter-plugin-resilience4j ....... SUCCESS [  0.702 s]
[INFO] soul-plugin-tars ................................... SUCCESS [  1.164 s]
[INFO] soul-spring-boot-starter-plugin-tars ............... SUCCESS [  0.676 s]
[INFO] soul-plugin-context-path ........................... SUCCESS [  0.696 s]
[INFO] soul-spring-boot-starter-plugin-context-path ....... SUCCESS [  0.598 s]
[INFO] soul-sync-data-zookeeper ........................... SUCCESS [  0.827 s]
[INFO] soul-spring-boot-starter-sync-data-center .......... SUCCESS [  0.030 s]
[INFO] soul-spring-boot-starter-sync-data-zookeeper ....... SUCCESS [  0.830 s]
[INFO] soul-sync-data-websocket ........................... SUCCESS [  0.858 s]
[INFO] soul-spring-boot-starter-sync-data-websocket ....... SUCCESS [  0.799 s]
[INFO] soul-sync-data-http ................................ SUCCESS [  0.909 s]
[INFO] soul-spring-boot-starter-sync-data-http ............ SUCCESS [  0.719 s]
[INFO] soul-sync-data-nacos ............................... SUCCESS [  0.874 s]
[INFO] soul-spring-boot-starter-sync-data-nacos ........... SUCCESS [  0.798 s]
[INFO] soul-client ........................................ SUCCESS [  0.019 s]
[INFO] soul-client-common ................................. SUCCESS [  0.791 s]
[INFO] soul-client-http ................................... SUCCESS [  0.024 s]
[INFO] soul-client-springmvc .............................. SUCCESS [  0.874 s]
[INFO] soul-spring-boot-starter-client .................... SUCCESS [  0.025 s]
[INFO] soul-spring-boot-starter-client-springmvc .......... SUCCESS [  0.678 s]
[INFO] soul-client-springcloud ............................ SUCCESS [  0.798 s]
[INFO] soul-spring-boot-starter-client-springcloud ........ SUCCESS [  0.714 s]
[INFO] soul-client-dubbo .................................. SUCCESS [  0.020 s]
[INFO] soul-client-dubbo-common ........................... SUCCESS [  0.851 s]
[INFO] soul-client-alibaba-dubbo .......................... SUCCESS [  0.892 s]
[INFO] soul-spring-boot-starter-client-alibaba-dubbo ...... SUCCESS [  0.689 s]
[INFO] soul-client-apache-dubbo ........................... SUCCESS [  0.804 s]
[INFO] soul-spring-boot-starter-client-apache-dubbo ....... SUCCESS [  0.697 s]
[INFO] soul-client-sofa ................................... SUCCESS [  1.028 s]
[INFO] soul-spring-boot-starter-client-sofa ............... SUCCESS [  0.674 s]
[INFO] soul-client-tars ................................... SUCCESS [  0.861 s]
[INFO] soul-spring-boot-starter-client-tars ............... SUCCESS [  0.668 s]
[INFO] soul-bootstrap ..................................... SUCCESS [  1.168 s]
[INFO] soul-register-center ............................... SUCCESS [  0.025 s]
[INFO] soul-register-common ............................... SUCCESS [  0.617 s]
[INFO] soul-register-client ............................... SUCCESS [  0.018 s]
[INFO] soul-register-client-api ........................... SUCCESS [  0.646 s]
[INFO] soul-register-client-http .......................... SUCCESS [  0.608 s]
[INFO] soul-register-client-zookeeper ..................... SUCCESS [  0.545 s]
[INFO] soul-register-server ............................... SUCCESS [  0.019 s]
[INFO] soul-register-server-api ........................... SUCCESS [  0.592 s]
[INFO] soul-register-server-http .......................... SUCCESS [  0.549 s]
[INFO] soul-register-server-zookeeper ..................... SUCCESS [  0.536 s]
[INFO] soul-dist .......................................... SUCCESS [  0.019 s]
[INFO] soul-admin-dist .................................... SUCCESS [  5.363 s]
[INFO] soul-bootstrap-dist ................................ SUCCESS [  4.173 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:32 min
[INFO] Finished at: 2021-01-14T22:20:37+08:00
[INFO] ------------------------------------------------------------------------

3、Idea 导入源码并运行 soul-admin 和 soul-bootstrap

首先使用 idea 导入源码,导入源码成功后,需要修改 soul-admin 中的 application.yml 配置文件中的数据库部分,当然前提是需要准备好 mysql 环境,这个也请童鞋自己准备吧,毕竟不是个复杂的过程,如下:

spring:
  #profiles:
  #  active: h2
  thymeleaf:
    cache: true
    encoding: utf-8
    enabled: true
    prefix: classpath:/static/
    suffix: .html
  datasource:
    url: jdbc:mysql://localhost:3306/soul?useUnicode=true&characterEncoding=utf-8
    username: root
    password: ****(如果mysql有秘密则设置)
    driver-class-name: com.mysql.jdbc.Driver

启动 soul-admin 和 soul-bootstrap 成功后访问:http://localhost:9095/#/home,然后登陆,成功后界面如下:
图片

总结

本文首先从网关的概念出发,了解了什么是网关,然后介绍了 Zuul 和 Gateway 两个 Spring Cloud 中的网关,介绍的原因是每一个框架的发展都有历史背景的。最后介绍了 Soul 网关,因为 Soul 网关参考过 KONG、Gateway。由此了解到Soul 是高性能、高可用、异步、响应式的 API 网关,采用插件化设计思想,易拓展,支持集群部署。后面将会以此逐步进行分析(笔者最后还会对已经过时的 Zuul 网关和正盛的 Gateway 网关进行相应的分析。

猜你喜欢

转载自blog.csdn.net/zfy163520/article/details/112652311