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 处理步骤:
- 创建一条线程通过类似 Zuul 的过滤器拦截请求;
- 对源服务器转发请求,注意这里 Gateway 并不会等待请求调用源服务器的过程,而是将处理线程挂起,以此来不占用资源;
- 等源服务器返回消息后,再通过寻址的方式来响应之前客户发送的请求;
从上面的执行流程中,可以知道 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 成功后访问:IT虾米网,然后登陆,成功后界面如下:
总结
本文首先从网关的概念出发,了解了什么是网关,然后介绍了 Zuul 和 Gateway 两个 Spring Cloud 中的网关,介绍的原因是每一个框架的发展都有历史背景的。最后介绍了 Soul 网关,因为 Soul 网关参考过 KONG、Gateway。由此了解到Soul 是高性能、高可用、异步、响应式的 API 网关,采用插件化设计思想,易拓展,支持集群部署。后面将会以此逐步进行分析(笔者最后还会对已经过时的 Zuul 网关和正盛的 Gateway 网关进行相应的分析。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/aiops/1284.html