1、简介
- 官网文档:https://shenyu.apache.org/zh/docs/index
- 仓库地址:https://github.com/apache/shenyu
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
- 找到
- 运行
ShenyuBootstrapApplication
- 该项目默认端口为:9195,后面设置路由规则需要用到
shenyu-bootstrap
子项目,修改application.yml
中shenyu.local.enabled
的值为true
,方便本地调试。
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、单一职责插件
divide,于是本次探究我们围绕divide
插件展开
3.2、divide插件
-
shenyu-plugin-divdie,可以看到
DividePlugin
类,该类继承自org.apache.shenyu.plugin.base.AbstractShenyuPlugin
,与官方文档描述如出一辙 -
org.apache.shenyu.plugin.base.AbstractShenyuPlugin.execute方法中打断点调试如下:
-
那么一个请求过来?网关是如何找到具体插件的呢?
shenyu项目下,可以看到一个子模块shenyu-plugin
,点开后可以看到该模块下已经提供了众多插件实现
3.3、ShenyuWebHandler
-
ShenyuWebHandler类实现了
org.springframework.web.server.WebHandler
接口。 -
然后通过责任链机制,按照插件定义的顺序依次匹配。未匹配上则忽略,匹配上则由对应的插件处理,正好与3.2步骤中的divide插件衔接上。匹配逻辑如下:
org.apache.shenyu.web.handler.ShenyuWebHandler.handle过来:
3.4、shenyu-spring-boot-starter-gateway
-
ObjectProvider<List<ShenyuPlugin>> plugins获取,因此我们只要找到插件Bean实例生成的位置即可
继续追溯,发现ShenyuWebHandler
实例的生产地位于shenyu-spring-boot-starter-gateway
中的ShenyuConfiguration
类
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发布出去5、联系我吧
我是一个热爱开源的小菜鸡,如果本文吸引到了你,欢迎通过下面的方式与我取得联系
- 本文作者:傲世孤尘,dromara社区开源项目(neutrino-proxy作者
- 微信号:yuyunshize
- 中微子代理(neutrino-proxy:一款基于netty的开源的内网穿透神器
- 中微子代理文档:https://dromara.gitee.io/neutrino-proxy
- 中微子代理仓库:https://gitee.com/dromara/neutrino-proxy