1、简介

这是一个异步的,高性能的,跨语言的,响应式的 API 网关。

2、首次体验

本次体验基本参照官方快速开始文档步骤

2.1、本地环境

  • 开发工具:IDEA
  • JDK:1.8

2.2、下载代码

git clone https://github.com/apache/shenyu.git
cd shenyu
mvn clean install -Dmaven.javadoc.skip=true -B -Drat.skip=true -Djacoco.skip=true -DskipITs -DskipTests

2.3、启动shenyu-admin

  • IDEA打开上一步下载好的项目
  • 找到shenyu-admin子项目,运行ShenyuAdminBootstrap
  • 该项目默认使用H2数据库,首次启动会自行初始化。默认web端口为:9095,默认账号密码为:admin/123456
  • 浏览器访问:http://localhost:9095 并登陆,可以看到如下界面:

2.4、启动shenyu-bootstrap

  • 找到shenyu-bootstrap子项目,修改application.ymlshenyu.local.enabled的值为true,方便本地调试。
  • 运行ShenyuBootstrapApplication
  • 该项目默认端口为:9195,后面设置路由规则需要用到

2.5、测试准备

  • 由于首次体验我们需要测试http接口转发,因此本地启动用于测试的web项目,提供一个待测试的接口:http://localhost:8081/test/hello 如下图:

2.6、添加路由规则

待测试的接口准备好了,接下来我们需要在ShenYu中添加路由规则,我直接通过终端发送请求如下:

curl --location --request POST 'http://localhost:9195/shenyu/plugin/selectorAndRules' \
--header 'Content-Type: application/json' \
--header 'localKey: 123456' \
--data-raw '{
"pluginName": "divide",
"selectorHandler": "[{\"upstreamUrl\":\"127.0.0.1:8081\"}]",
"conditionDataList": [{
"paramType": "uri",
"operator": "match",
"paramValue": "/**"
}],
"ruleDataList": [{
"ruleHandler": "{\"loadBalance\":\"random\"}",
"conditionDataList": [{
"paramType": "uri",
"operator": "match",
"paramValue": "/**"
}]
}]
}'

2.7、测试转发

根据上面的映射规则,我们直接访问: http://localhost:9195/test/hello ,结果如下:

至此,首次体验已经完成。接下来,我想继续了解下本项目。

3、转发实现流程探究

以下的探究基于上面2.x体验流程

3.1、单一职责插件

通过官方文档:https://shenyu.apache.org/zh/docs/developer/custom-plugin ,可以看到如下内容:

结合2.6添加路由规则中涉及的plugin:divide,于是本次探究我们围绕divide插件展开

3.2、divide插件

  • shenyu项目下,可以看到一个子模块shenyu-plugin,点开后可以看到该模块下已经提供了众多插件实现

  • 点开shenyu-plugin-divdie,可以看到DividePlugin类,该类继承自org.apache.shenyu.plugin.base.AbstractShenyuPlugin,与官方文档描述如出一辙

  • org.apache.shenyu.plugin.base.AbstractShenyuPlugin.execute方法中打断点调试如下:

  • 此处正好印证官方文档关于插件的描述,具体的转发逻辑由插件各自实现,我们可以通过自定义插件的方式进行扩展

  • 那么一个请求过来?网关是如何找到具体插件的呢?

3.3、ShenyuWebHandler

  • 断点通过方法调用栈发现,该请求从上游方法org.apache.shenyu.web.handler.ShenyuWebHandler.handle过来:

  • ShenyuWebHandler类实现了org.springframework.web.server.WebHandler接口。

  • 可以看到,该handler方法拿到了plugins,并通过Reactor异步地将exchange发布出去

  • 然后通过责任链机制,按照插件定义的顺序依次匹配。未匹配上则忽略,匹配上则由对应的插件处理,正好与3.2步骤中的divide插件衔接上。匹配逻辑如下:

  • 由于这是首次体验,我不想过多的探究细节,因此插件匹配、执行的细节此处暂且跳过,我们继续往下探究plugins从何而来?

3.4、shenyu-spring-boot-starter-gateway

  • 继续追溯,发现ShenyuWebHandler实例的生产地位于shenyu-spring-boot-starter-gateway中的ShenyuConfiguration

  • 通过该方法发现,插件列表信息从方法参数ObjectProvider<List<ShenyuPlugin>> plugins获取,因此我们只要找到插件Bean实例生成的位置即可

3.5、shenyu-spring-boot-starter-plugin-divide

  • 于是很轻易的发现,在shenyu-spring-boot-starter-plugin-divide子项目下,有一个类:DividePluginConfiguration,包含如下代码:

  • 因此,本次探究过程至此结束

4、本次学习总结

  • 项目主要模块

    • shenyu-admin:后台配置、监控
    • shenyu-bootstrap:服务端配置、启动入口
    • shenyu-plugin:服务端插件合集
    • shenyu-web: 服务端web层上游基础功能封装
    • shenyu-spring-boot-starter:将其他功能模块与springboot进行整合
  • 插件开发大致流程
    • shenyu-plugin下新建插件子模块,编写插件入口类(实现ShenyuPlugin接口,或继承AbstractShenyuPlugin类)
    • 定义好插件名称、优先级(Order)、skip逻辑、插件处理逻辑(execute)
    • shenyu-spring-boot-starter-plugin编写自定义插件对应的starter
  • 转发大致流程
    • 项目启动后,从bean容器加载插件列表
    • 请求过来后,首先到达org.apache.shenyu.web.handler.ShenyuWebHandler.handle,通过Reactor异步地将exchange发布出去
    • 然后通过责任链机制,按照插件定义的顺序依次匹配。未匹配上则忽略,匹配上则由对应的插件处理
    • 最后由具体的插件(如:divide插件,将http请求转发到目标地址)处理

5、联系我吧

我是一个热爱开源的小菜鸡,如果本文吸引到了你,欢迎通过下面的方式与我取得联系

Apache ShenYu 学习笔记一的更多相关文章

  1. Apache Flink学习笔记

    Apache Flink学习笔记 简介 大数据的计算引擎分为4代 第一代:Hadoop承载的MapReduce.它将计算分为两个阶段,分别为Map和Reduce.对于上层应用来说,就要想办法去拆分算法 ...

  2. Apache OFBiz 学习笔记 之 服务引擎 二

    加载服务定义文件   ofbiz-component.xml:所有的服务定义文件在每个组件的ofbi-component.xml文件中   加载服务定义 例:framework/common/ofbi ...

  3. Apache Ignite 学习笔记(一): Ignite介绍、部署安装和REST/SQL客户端使用

    Apache Ignite 介绍 Ignite是什么呢?先引用一段官网关于Ignite的描述: Ignite is memory-centric distributed database, cachi ...

  4. Apache Lucene学习笔记

    Hadoop概述 Apache lucene: 全球第一个开源的全文检索引擎工具包 完整的查询引擎和搜索引擎 部分文本分析引擎 开发人员在此基础建立完整的全文检索引擎 以下为转载:http://www ...

  5. apache activemq 学习笔记

    0.activemq的概念 activemq实现了jms(java Message server),用于接收,发送,处理消息的开源消息总线. 1.activemq和jms的区别 jms说白了就是jav ...

  6. Apache服务器学习笔记

    Apache服务器知识 首先我们要知道一共有那几个程序在监听网络端口,即与网络保持活跃连接,打开CMD命令窗口 输入: netstat  –an 指令就能显示出所有与网络保持连接的程序,输入net s ...

  7. Apache Hadoop学习笔记一

    官网:http://hadoop.apache.org/ 1 什么是Hadoop? Apache™Hadoop®项目开发了用于可靠,可扩展的分布式计算的开源软件. Apache Hadoop软件库是一 ...

  8. Apache Flume 学习笔记

    # 从http://flume.apache.org/download.html 下载flume ############################################# # 概述: ...

  9. Apache Ignite 学习笔记(四): Ignite缓存冗余备份策略

    Ignite的数据网格是围绕着基于内存的分布式key/value存储能力打造的.当初技术选型的时候,决定用Ignite也是因为虽然同样是key/value存储,它有着和其他key/value存储系统不 ...

  10. Apache Ignite 学习笔记(三): Ignite Server和Client节点介绍

    在前两篇文章中,我们把Ignite集群当做一个黑盒子,用二进制包自带的脚本启动Ignite节点后,我们用不同的客户端连接上Ignite进行操作,展示了Ignite作为一个分布式内存缓存,内存数据库的基 ...

随机推荐

  1. 一道测试Java值传递的题目

    请给出下列代码的执行结果: public class T3 { public static void main(String[] args) { T3 t3 = new T3(); t3.first( ...

  2. Java学习笔记-BigDecimal类型

    1.介绍 Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更 ...

  3. nginx Redis 不能访问问题

    开始以为     proxy_cookie_path    /report/     /; 没有配置 配置后还是访问了,老的session 就过期 本地代理主程序,访问本地的 /report/ 可以 ...

  4. SQL语句用法总结

    use quan56_goods; 使用数据库 show tables; 展示数据表 模糊查询 select * from tb_brand where name like '%林%'; 顺序 书写顺 ...

  5. 在app中如何使weib-view不铺满全屏,自适应页面

    // #ifdef APP-PLUS //自建webview var currentWebview = this.$scope.$getAppWebview(); var height = this. ...

  6. Repeater 绑定数据如何根据数据列的内容排序

    可指定Repeater的数据源 从数据库查询时直接排序,而后绑定数据这样

  7. 【CS231n assignment 2022】Assignment 2 - Part 2,优化器,批归一化以及层归一化

    前言 博客主页:睡晚不猿序程 首发时间:2022.7.23 最近更新时间:2022.7.23 本文由 睡晚不猿序程 原创 作者是蒻蒟本蒟,如果文章里有任何错误或者表述不清,请 tt 我,万分感谢!or ...

  8. 玩转SpringBoot原理:掌握核心技术,成为高级开发者

    本文通过编写一个自定义starter来学习springboot的底层原理,帮助我们更好的使用springboot集成第三方插件 步骤一:创建项目 步骤二:添加依赖 步骤三:创建自动配置类 步骤四:创建 ...

  9. Bitcask — 日志结构的快速 KV 存储引擎

    Bitcask 介绍 Bitcask 是一种高性能的键值存储引擎,基于日志结构和哈希索引来提供高速的读写操作和数据持久性,适用于处理大量写入请求和快速查找键值对的应用场景. 核心概念 Bitcask ...

  10. 剑指 offer 第 8 天

    第 8 天 动态规划(简单) 剑指 Offer 10- I. 斐波那契数列 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N)).斐波那契数列的定义如下: F(0) ...