Apache ShenYu 学习笔记一
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.yml
中shenyu.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、联系我吧
我是一个热爱开源的小菜鸡,如果本文吸引到了你,欢迎通过下面的方式与我取得联系
- 本文作者:傲世孤尘,dromara社区开源项目(neutrino-proxy)作者
- 微信号:yuyunshize
- 中微子代理(neutrino-proxy):一款基于netty的开源的内网穿透神器
- 中微子代理文档:https://dromara.gitee.io/neutrino-proxy
- 中微子代理仓库:https://gitee.com/dromara/neutrino-proxy
Apache ShenYu 学习笔记一的更多相关文章
- Apache Flink学习笔记
Apache Flink学习笔记 简介 大数据的计算引擎分为4代 第一代:Hadoop承载的MapReduce.它将计算分为两个阶段,分别为Map和Reduce.对于上层应用来说,就要想办法去拆分算法 ...
- Apache OFBiz 学习笔记 之 服务引擎 二
加载服务定义文件 ofbiz-component.xml:所有的服务定义文件在每个组件的ofbi-component.xml文件中 加载服务定义 例:framework/common/ofbi ...
- Apache Ignite 学习笔记(一): Ignite介绍、部署安装和REST/SQL客户端使用
Apache Ignite 介绍 Ignite是什么呢?先引用一段官网关于Ignite的描述: Ignite is memory-centric distributed database, cachi ...
- Apache Lucene学习笔记
Hadoop概述 Apache lucene: 全球第一个开源的全文检索引擎工具包 完整的查询引擎和搜索引擎 部分文本分析引擎 开发人员在此基础建立完整的全文检索引擎 以下为转载:http://www ...
- apache activemq 学习笔记
0.activemq的概念 activemq实现了jms(java Message server),用于接收,发送,处理消息的开源消息总线. 1.activemq和jms的区别 jms说白了就是jav ...
- Apache服务器学习笔记
Apache服务器知识 首先我们要知道一共有那几个程序在监听网络端口,即与网络保持活跃连接,打开CMD命令窗口 输入: netstat –an 指令就能显示出所有与网络保持连接的程序,输入net s ...
- Apache Hadoop学习笔记一
官网:http://hadoop.apache.org/ 1 什么是Hadoop? Apache™Hadoop®项目开发了用于可靠,可扩展的分布式计算的开源软件. Apache Hadoop软件库是一 ...
- Apache Flume 学习笔记
# 从http://flume.apache.org/download.html 下载flume ############################################# # 概述: ...
- Apache Ignite 学习笔记(四): Ignite缓存冗余备份策略
Ignite的数据网格是围绕着基于内存的分布式key/value存储能力打造的.当初技术选型的时候,决定用Ignite也是因为虽然同样是key/value存储,它有着和其他key/value存储系统不 ...
- Apache Ignite 学习笔记(三): Ignite Server和Client节点介绍
在前两篇文章中,我们把Ignite集群当做一个黑盒子,用二进制包自带的脚本启动Ignite节点后,我们用不同的客户端连接上Ignite进行操作,展示了Ignite作为一个分布式内存缓存,内存数据库的基 ...
随机推荐
- samba缓存问题
samba 在第一次登录时,会在windows上缓存着登录密码,当你重新修改samba服务端的密码, 再次登录时,windows会自动用缓存的旧密码登录,导致的登录失败.
- 用echarts做兼容ie8的三测单(体温单) 代码全
$.fn.extend({ /** * * @param { * UrineOutputData: 尿量数据 * OutputData: 出量数据 * InputData: 入量数据 * shitDa ...
- UniDBGrid控件的几个功能优化
内容自动换行 默认UniDBGrid的cell内的内容如果超出表格列宽并不自动换行和调整行高,给客户带来极大的不方便,通过修改ServerModule的属性CustomCSS可以实现. <sty ...
- 02-Spring基于XML的Bean属性注入
属性值注入:就是给属性赋值 创建一个Account类: public class Account implements Serializable { private int aid; private ...
- OO多项式求导作业总结
一.程序分析 1.1第一次作业 第一次作业是简单的多项式求导,甚至没有括号嵌套.但是,就是这个在如今看来如此简单的作业,由于俺寒假过于起飞,pre没做,正则表达式也不会(属实拉跨),一度想用c语言字符 ...
- CSS伪类三角形
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Double-Checked Locking 双重检查锁问题
Code Correctness: Double-Checked Locking Abstract Double-checked locking 是一种不正确的用法,并不能达到预期目标. Explan ...
- 再谈回声消除测评丨Dev for Dev 专栏
本文为「Dev for Dev 专栏」系列内容,作者为声网音视频实验室工程师 黄译庆. 音频质量的优化是一个复杂的系统工程,回声消除是其中一个老生常谈的话题,一般来说,回声消除的效果受设备本身的声学设 ...
- windows作业系统部署nfs服务
文件共享的需求是如何产生的? 据说当年美国和苏联冷战期间,双方都有摧毁对方的能力.而苏联 不怕死的性格让美国人多少有些害怕.美国当时害怕自己的军事指挥中心被苏联摧毁.于是,美国建立了阿帕网,并把自己的 ...
- 一站式微服务治理中台,Water v2.10.2 发布
Water(水孕育万物...) Water 为项目开发.服务治理,提供一站式解决方案(可以理解为微服务架构支持套件).基于 Solon 框架开发,并支持完整的 Solon Cloud 规范:已在生产环 ...