点击上方“芋道源码”,选择“设为星标”
管她前浪,还是后浪?
能浪的浪,才是好浪!
每天 8:55 更新文章,每天掉亿点点头发...
源码精品专栏
原创 | Java 2020 超神之路,很肝~
中文详细注释的开源项目
RPC 框架 Dubbo 源码解析
网络应用框架 Netty 源码解析
消息中间件 RocketMQ 源码解析
数据库中间件 Sharding-JDBC 和 MyCAT 源码解析
作业调度中间件 Elastic-Job 源码解析
分布式事务中间件 TCC-Transaction 源码解析
Eureka 和 Hystrix 源码解析
Java 并发源码
摘要: 原创出处 http://www.iocoder.cn/Soul/install/ 「芋道源码」欢迎转载,保留摘要,谢谢!
1. 概述
2. 单机部署
3. 接入 Dubbo 应用
4. 接入 Spring Boot 应用
5. 接入 Spring Cloud 应用
6. rateLimiter 插件
7. hystrix 插件
666. 彩蛋
Soul 是基于 WebFlux 实现的响应式的 API 网关,具有异步、高性能、跨语言等特点。
作者:我希望能够有一样东西像灵魂一样,保护您的微服务。在参考了 Kong、Spring Cloud Gateway 等优秀的网关后,站在巨人的肩膀上,Soul 由此诞生!
作者是艿艿的大表弟,胖友信么?!
目前 Soul 功能列表如下:
支持各种语言,无缝集成到 Dubbo、Spring Cloud、Spring Boot 中。
Soul 是极其少支持 Dubbo 的 API 网关,通过 Dubbo 泛化调用 实现。
丰富的插件支持,鉴权,限流,熔断,防火墙等等。
网关多种规则动态配置,支持各种策略配置。
插件热插拔,易扩展。
支持集群部署,支持 A/B Test。
整体架构如下图所示:
架构图是不是看着就贼酷炫,实际一脸懵逼。不要慌~我们先来搭建 Soul 网关。
本小节,我们来单机部署一个 Soul 服务,适合测试环境。如下图所示:
Soul 单机部署相信大家都会,艿艿就不瞎哔哔了。嘿嘿~注意,目前最好安装 5.X 版本,艿艿一开始用 8.X 存在报错的情况。
安装完成后,创建 soul
数据库。
Soul Admin 控制台,负责维护网关的元数据、配置等等,并提供给 Soul Bootstrap 网关服务读取。
友情提示:后续推荐胖友阅读如下两篇文章,搞懂 Soul Admin 和 Soul Bootstrap 的同步的原理:
《Soul 文档 —— 数据配置流程》
《Soul 文档 —— 数据同步原理》
① 从 https://yu199195.github.io/jar/soul-admin.jar 下载启动 jar 包。
# 创建目录
$ mkdir -p /Users/yunai/Soul
$ cd /Users/yunai/Soul
# 下载
$ wget https://yu199195.github.io/jar/soul-admin.jar
② 通过 java -jar soul-admin.jar
命令启动 Soul Admin 控制台。完整命令如下:
$ java -jar soul-admin.jar --spring.datasource.url="jdbc:mysql://s1.iocoder.cn:3306/soul?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&failOverReadOnly=false&autoReconnect=true&useSSL=false" --spring.datasource.username='root' --spring.datasource.password='3WLiVUBEwTbvAfsh'
--spring.datasource.url
配置项,修改成胖友的数据库地址。
--spring.datasource.username
配置项,修改成胖友的数据库账号。
--spring.datasource.password
配置项,修改成胖友的数据库密码。
Soul Admin 会自动创建数据库,以及表结构,并初始化默认数据。如下图所示:
soul
数据库
友情提示:具体的数据库设计,后续可以看看《Soul 文档 —— 数据库设计》。
③ 启动完成后,我们可以通过日志看到 Soul Admin 启动在 9095 端口。使用浏览器,访问 http://127.0.0.1:9095/ 地址,进入登录页。
Soul Admin - 登录页默认内置管理员账号「admin/123456」。输入账号密码,进入首页。
Soul Admin - 首页胖友可以自己随便点点,简单了解下有哪些功能。
Soul Bootstrap 网关服务,负责启动网关,并转发请求到后端服务。
① 从 https://yu199195.github.io/jar/soul-bootstrap.jar 下载启动 jar 包。
$ wget https://yu199195.github.io/jar/soul-bootstrap.jar
② 直接通过 java -jar soul-bootstrap.jar
命令启动 Soul Bootstrap 网关服务。完整命令如下:
$ java -jar soul-bootstrap.jar --soul.sync.websocket.url="ws://localhost:9095/websocket"
--spring.datasource.url
配置项,修改成胖友的 Soul Admin 地址。
同时,我们在 Soul Admin 的日志输出如下日志,说明 Soul Bootstrap 成功连接上。
2020-05-22 20:32:48.005 INFO 48891 --- [0.0-9095-exec-1] o.d.s.a.l.websocket.WebsocketCollector : websocket on open successful....
③ 启动完成后,我们可以通过日志看到 Soul Bootstrap 启动在 9195 端口。使用浏览器,访问 http://127.0.0.1:9195/ 地址,返回如下结果,说明启动成功。
{
"code": -100,
"message": "您的参数错误,请检查相关文档!",
"data": null
}
至此,我们已经完成了 Soul 服务的单机部署,是不是挺简单的。下面,胖友可以根据自己的需要,阅读如下小节:
「3. 接入 Dubbo 应用」
「4. 接入 Spring Boot 应用」
「5. 接入 Spring Cloud 应用」
示例代码对应仓库:
lab-60-soul-dubbo-demo-user-service
本小节,我们参考《Soul 文档 —— Dubbo 用户接入》文章,接入 Soul 服务网关。整个示例架构如下图所示:
示例的整体架构下面,我们来开始正式接入 Dubbo 应用。
先需要设置 dubbo 插件 的注册中心,因为 Soul Bootstrap 服务网关需要从注册中心获取到 Dubbo 服务的实例列表。
① 使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 dubbo 插件。如下图所示:
系统管理 -> 插件管理② 点击 dubbo 插件的「编辑」按钮,设置注册中心的配置。如下图所示:
系统管理 -> 插件管理 -> 编辑因为我们将使用 Nacos 作为 Dubbo 服务的注册中心,所以这里设置为 {"register":"nacos://localhost:8848"}
。
如果胖友使用 Zookeeper 作为 Dubbo 服务的注册中心,所以这里设置为 {"register":"zookeeper://localhost:2181"}
。
友情提示:注册中心的地址,记得要填写正确哈~
③ 因为 Soul Bootstrap 和 Soul Admin 暂时不支持插件修改的自动加载,所以我们此时需要手动重启下。
先快速搭建一个 Dubbo 示例项目,暂未接入 Soul 网关。如下图所示:
项目结构lab-60-soul-dubbo-demo-user-service-api
lab-60-soul-dubbo-demo-user-service
友情提示:如果胖友对 Dubbo + Nacos 不了解的胖友,可以阅读《芋道 Spring Boot Dubbo 入门》文章。
下面,我们来将它改造接入 Soul 网关。
修改 pom.xml
文件,引入 soul-client-apache-dubbo
依赖,它是 Soul 对 Apache Dubbo 2.7.X 的集成支持。
org.dromara
soul-client-apache-dubbo
2.1.2-RELEASE
友情提示:如果胖友使用 Alibaba Dubbo 2.6.X 的话,引入
soul-client-alibaba-dubbo
依赖。
修改 application.yaml
配置文件,添加 Soul 配置项如下:
soul:
# Soul 针对 Dubbo 的配置项,对应 DubboConfig 配置类
dubbo:
admin-url: http://127.0.0.1:9095 # Soul Admin 地址
context-path: /user-api # 设置在 Soul 网关的路由前缀,例如说 /order、/product 等等。
# 后续,网关会根据该 context-path 来进行路由
app-name: user-service # 应用名。未配置情况下,默认使用 Dubbo 的应用名
soul.dubbo
配置项,Soul 对 Dubbo 的配置项,对应 DubboConfig 配置类。具体每个配置项的作用,胖友自己看配置项后的注释。
需要在 Dubbo Service 实现类的方法上,添加 @SoulClient
注解,用于设置每个 Dubbo 方法对应的请求路径。这里,我们修改 UserServiceImpl 类,添加该注解。代码如下:
@org.apache.dubbo.config.annotation.Service(version = "1.0.0")
public class UserServiceImpl implements UserService {
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
@SoulClient(path = "/user/get", desc = "获得用户详细")
public String getUser(Integer id) {
return "User:" + id;
}
@Override
@SoulClient(path = "/user/create", desc = "创建用户")
public Integer createUser(UserCreateDTO createDTO) {
logger.info("[createUser][username({}) password({})]", createDTO.getNickname(), createDTO.getGender());
return 1;
}
}
@SoulClient
注解一共有三个属性:
path
:映射的 HTTP 接口的请求路径。
desc
:接口的描述,便于知道其用途。
enable
:是否开启,默认为 true
开启。
后续,在 Dubbo 服务启动时,Soul Client 会自动解析 @SoulClient
注解的 Dubbo 方法,写入方法的元数据到 Soul Admin 控制台,最终通知到 Soul Bootstrap 服务网关上。
① 执行 UserServiceApplication 启动 Dubbo 服务。在 IDEA 控制台可以看到如下日志,看到写入 Dubbo 方法的元数据到 Soul Admin 控制台。
2020-05-23 01:27:56.682 INFO 54370 --- [pool-2-thread-1] .d.s.c.d.s.DubboServiceBeanPostProcessor : dubbo client register success :{} {"appName":"user-service","path":"/user-api/user/get","pathDesc":"获得用户详细","rpcType":"dubbo","serviceName":"cn.iocoder.springboot.lab60.userservice.api.UserService","methodName":"getUser","parameterTypes":"java.lang.Integer","rpcExt":"{\"version\":\"1.0.0\"}","enabled":true}
2020-05-23 01:27:56.944 INFO 54370 --- [pool-2-thread-1] .d.s.c.d.s.DubboServiceBeanPostProcessor : dubbo client register success :{} {"appName":"user-service","path":"/user-api/user/create","pathDesc":"创建用户","rpcType":"dubbo","serviceName":"cn.iocoder.springboot.lab60.userservice.api.UserService","methodName":"createUser","parameterTypes":"cn.iocoder.springboot.lab60.userservice.api.dto.UserCreateDTO","rpcExt":"{\"version\":\"1.0.0\"}","enabled":true}
② 使用浏览器,访问 http://127.0.0.1:9095/#/system/metadata 地址,进入「系统管理 -> 元数据」菜单,可以看到上述注册的元数据。如下图所示:
系统管理 -> 元数据③ 使用浏览器,访问 http://127.0.0.1:9095/#/plug/dubbo 地址,进入「插件列表 -> Dubbo」菜单,看到选择器和规则。如下图所示:
插件列表 -> Dubbo点击选择器 /user-api
的「编辑」按钮,查看该选择器的具体信息。如下图所示:
点击规则 /user-api/user/get
的「编辑」按钮,查看该规则的具体信息。如下图所示:
④ 使用 Postman 模拟请求 http://127.0.0.1:9195/user-api/user/get 地址,调用 UserServiceImpl#getUser(Integer id)
方法。如下图所示:
使用 Request Method 为 POST
。
请求内容类型为 application/json
。
因为 UserServiceImpl#getUser(Integer id)
方法是非 Bean 参数类型,所以直接在 Request Body 输入具体值即可。
⑤ 使用 Postman 模拟请求 http://127.0.0.1:9195/user-api/user/create 地址,调用 UserServiceImpl#createUser(UserCreateDTO createDTO)
方法。如下图所示:
使用 Request Method 为 POST
。
请求内容类型为 application/json
。
因为 UserServiceImpl#createUser(UserCreateDTO createDTO)
方法是 Bean 参数类型,所以直接在 Request Body 输入 JSON 数据格式。
至此,我们已经完成了 Soul 网关接入 Dubbo 应用,并进行相应的而测试。
友情提示:实际上,我们也可以参考《Soul 文档 —— dubbo 插件》,手动在 Soul Admin 控制台配置 Dubbo 接口方法的元数据,以及进行 dubbo 插件的选择器和规则的设置,实现 Soul Bootstrap 服务网关转发请求到 Dubbo 服务,无需在 Dubbo 项目中引入
soul-client-apache-dubbo
依赖。也就是说,引入
soul-client-apache-dubbo
依赖的目的,是为了实现自动化,毕竟手工配置比较麻烦,并且容易出错。
示例代码对应仓库:
lab-60-soul-spring-boot-demo
本小节,我们参考《Soul 文档 —— http 用户接入》文章,接入 Soul 服务网关。整个示例架构如下图所示:
示例的整体架构下面,我们来开始正式接入 Spring Boot 应用。
需要设置 divide 插件 为开启。该插件实现 HTTP 正向代理的功能,所有 HTTP 类型的请求你,都由它进行负载均衡的调用。
使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 divide 插件。如下图所示:
系统管理 -> 插件管理默认情况下,divide 插件已经是开启状态,所以无需开启。
因为 Soul 网关需要知道后端 Spring Boot 应用的 host + port 地址,所以 Soul Client 实现使用 Zookeeper 作为注册中心,让 Spring Boot 应用注册到其上,从而使得 Soul 网关能够知道具体转发的地址。
① 参考《芋道 Zookeeper 极简入门》文章,先来搭建一个 Zookeeper 服务。
② 重启 Soul Admin 控制台,设置 --soul.http.zookeeper-url
配置项为 Zookeeper 地址。完整命令如下:
java -jar soul-admin.jar --spring.datasource.url="jdbc:mysql://s1.iocoder.cn:3306/soul?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&failOverReadOnly=false&autoReconnect=true&useSSL=false" --spring.datasource.username='root' --spring.datasource.password='3WLiVUBEwTbvAfsh' --soul.http.register=true --soul.http.zookeeper-url=127.0.0.1:2181
先快速搭建一个 Spring Boot 示例项目,暂未接入 Soul 网关。如下图所示:
项目结构lab-60-soul-spring-boot-demo
修改 pom.xml
文件,引入 soul-client-springmvc
依赖,它是 Soul 对 SpringMVC 的集成支持。
org.dromara
soul-client-springmvc
2.1.2-RELEASE
修改 application.yaml
配置文件,添加 Soul 配置项如下:
soul:
# Soul 针对 SpringMVC 的配置项,对应 SoulHttpConfig 配置类
http:
admin-url: http://127.0.0.1:9095 # Soul Admin 地址
context-path: /sb-demo-api # 设置在 Soul 网关的路由前缀,例如说 /order、/product 等等。
# 后续,网关会根据该 context-path 来进行路由
app-name: sb-demo-service # 应用名。未配置情况下,默认使用 `spring.application.name` 配置项
zookeeper-url: 127.0.0.1:2181 # 使用 Zookeeper 作为注册中心的地址
soul.http
配置项,Soul 对 SpringMVC 的配置项,对应 SoulHttpConfig 配置类。具体每个配置项的作用,胖友自己看配置项后的注释。
需要在 Controller 的 HTTP API 方法上,添加 @SoulClient
注解,用于设置每个 API 方法对应的请求路径。这里,我们修改 UserController 类,添加该注解。代码如下:
@RestController
@RequestMapping("/user")
public class UserController {
private Logger logger = LoggerFactory.getLogger(getClass());
@GetMapping("/get")
@SoulClient(path = "/user/get", desc = "获得用户详细")
public String getUser(@RequestParam("id") Integer id) {
return "DEMO:" + id;
}
@PostMapping("/create")
@SoulClient(path = "/user/create", desc = "创建用户")
public Integer createUser(@RequestBody UserCreateDTO createDTO) {
logger.info("[createUser][username({}) password({})]", createDTO.getNickname(), createDTO.getGender());
return 1;
}
}
@SoulClient
注解一共有三个属性:
path
:映射的 HTTP 接口的请求路径。
desc
:接口的描述,便于知道其用途。
enable
:是否开启,默认为 true
开启。
后续,在 Spring Boot 应用启动时,Soul Client 会自动解析 @SoulClient
注解的 API 方法,写入方法的元数据到 Soul Admin 控制台,最终通知到 Soul Bootstrap 服务网关上。
① 执行 DemoApplication 启动 Spring Boot 应用。在 IDEA 控制台可以看到如下日志,看到写入 HTTP API 方法的元数据到 Soul Admin 控制台。
// 注册到 Zookeeper
2020-05-23 10:50:39.587 INFO 62682 --- [ main] o.d.s.c.s.s.ApplicationStartListener : soul-http-client服务注册成功,context-path:/sb-demo-api, ip:port:10.171.1.115:8080
// 写入元数据
2020-05-23 10:50:39.911 INFO 62682 --- [pool-1-thread-1] o.d.s.c.s.s.SoulClientBeanPostProcessor : springMvc client register success :{} {"appName":"sb-demo-service","path":"/sb-demo-api/user/get","pathDesc":"获得用户详细","rpcType":"http","serviceName":"UserController","methodName":"getUser","parameterTypes":"java.lang.Integer","rpcExt":"","enabled":true}
2020-05-23 10:50:40.212 INFO 62682 --- [pool-1-thread-1] o.d.s.c.s.s.SoulClientBeanPostProcessor : springMvc client register success :{} {"appName":"sb-demo-service","path":"/sb-demo-api/user/create","pathDesc":"创建用户","rpcType":"http","serviceName":"UserController","methodName":"createUser","parameterTypes":"cn.iocoder.springboot.lab60.dto.UserCreateDTO","rpcExt":"","enabled":true}
② 使用浏览器,访问 http://127.0.0.1:9095/#/system/metadata 地址,进入「系统管理 -> 元数据」菜单,可以看到上述注册的元数据。如下图所示:
系统管理 -> 元数据③ 使用浏览器,访问 http://127.0.0.1:9095/#/plug/divide 地址,进入「插件列表 -> Divide」菜单,看到选择器和规则。如下图所示:
插件列表 -> Divide点击选择器 /sb-demo-api
的「编辑」按钮,查看该选择器的具体信息。如下图所示:
点击规则 /sb-demo-api/user/get
的「编辑」按钮,查看该规则的具体信息。如下图所示:
④ 使用 Postman 模拟请求 http://127.0.0.1:9195/sb-demo-api/user/get?id=1 地址,转发到 GET /user/get
接口上。如下图所示:
使用 Request Method 为 GET
。
请求参数,直接带在 URL 后面。
⑤ 使用 Postman 模拟请求 http://127.0.0.1:9195/sb-demo-api/user/create 地址,转发到 POST /user/create
接口上。如下图所示:
使用 Request Method 为 POST
。
请求内容类型为 application/json
。
因为 POST /user/create
使用 JSON 接参,所以直接在 Request Body 输入 JSON 数据格式。
至此,我们已经完成了 Soul 网关接入 Spring Boot 应用,并进行相应的而测试。
友情提示:实际上,我们也可以参考《Soul 文档 —— divide 插件》,手动在 Soul Admin 控制台配置 API 接口方法的元数据,以及进行 divide 插件的选择器和规则的设置,实现 Soul Bootstrap 服务网关转发请求到 Spring Boot 应用,无需在 Spring Boot 应用中引入
soul-client-springmvc
依赖。也就是说,引入
soul-client-springmvc
依赖的目的,是为了实现自动化,毕竟手工配置比较麻烦,并且容易出错。当然,这样也就无法使用 Zookeeper 作为注册中心,需要在 Soul Admin 中手动维护应用的实例列表,会比较麻烦~
示例代码对应仓库:
lab-60-soul-spring-cloud-demo
本小节,我们参考《Soul 文档 —— springcloud 用户接入》文章,接入 Soul 服务网关。整个示例架构如下图所示:
示例的整体架构下面,我们来开始正式接入 Spring Cloud 应用。
需要设置 springcloud 插件 为开启。该插件实现从 Spring Cloud 注册中心获取服务的示例列表,后续使用 Ribbon 实现负载均衡的调用。
使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 springcloud 插件。如下图所示:
系统管理 -> 插件管理默认情况下,springcloud 插件已经是开启状态,所以无需开启。
我们使用 Nacos 作为 Spring Cloud 应用的注册中心,所有胖友可以参照《Nacos 极简入门》文章,搭建一个 Nacos 注册中心。
友情提示:如果想要 Eureka 作为 Spring Cloud 应用注册中心的胖友,可以参照《芋道 Spring Cloud Netflix 注册中心 Eureka 入门》文章,搭建一个 Eureka 注册中心。
因为 Soul Bootstrap 需要从注册中心获取 Spring Cloud 应用的实例列表,所以需要集成 Spring Cloud 注册中心。目前,默认情况下 Soul Bootstrap 网关服务提供的 soul-bootstrap.jar
包,并未引入相关依赖,所以我们需要自己修改源码,并进行打包。
① 使用 IDEA 从 https://gitee.com/shuaiqiyu/soul 仓库中,下载最新的源码。如下图所示:
soul 源码② 修改 application.yml
配置文件,添加 spring.cloud.nacos.discovery.server-addr
配置项为 Nacos 注册中心的地址。如下图所示:
application.yml
配置文件
③ 修改 pom.xml
文件,引入 spring-cloud-starter-alibaba-nacos-discovery
依赖,集成 Nacos 作为 Spring Cloud 的注册中心。如下图所示:
pom.xml
文件
友情提示:如果想要 Eureka 作为 Spring Cloud 应用注册中心的胖友,也是修改配置文件,和引入依赖。
④ 关闭 soul-bootstrap.jar
启动的服务网关,在 IDEA 中执行 SoulBootstrapApplication 启动服务网关。美滋滋~
友情提示:启动时,会报
Connection refused: localhost/127.0.0.1:6379
错误,这是 Soul 限流功能需要使用到 Redis,可以暂时忽略。
先快速搭建一个 Spring Cloud 示例项目,暂未接入 Soul 网关。如下图所示:
项目结构lab-60-soul-spring-cloud-demo
修改 pom.xml
文件,引入 soul-client-springcloud
依赖,它是 Soul 对 Spring Cloud 的集成支持。
org.dromara
soul-client-springcloud
2.1.2-RELEASE
修改 application.yaml
配置文件,添加 Soul 配置项如下:
soul:
# Soul 针对 SpringMVC 的配置项,对应 SoulSpringCloudConfig 配置类
springcloud:
admin-url: http://127.0.0.1:9095 # Soul Admin 地址
context-path: /sc-user-service-api # 设置在 Soul 网关的路由前缀,例如说 /order、/product 等等。
# 后续,网关会根据该 context-path 来进行路由
app-name: sc-user-service # 应用名。未配置情况下,默认使用 `spring.application.name` 配置项
soul.springcloud
配置项,Soul 对 Spring Cloud 的配置项,对应 SoulSpringCloudConfig 配置类。具体每个配置项的作用,胖友自己看配置项后的注释。
需要在 Controller 的 HTTP API 方法上,添加 @SoulClient
注解,用于设置每个 API 方法对应的请求路径。这里,我们修改 UserController 类,添加该注解。代码如下:
@RestController
@RequestMapping("/user")
public class UserController {
private Logger logger = LoggerFactory.getLogger(getClass());
@GetMapping("/get")
@SoulClient(path = "/user/get", desc = "获得用户详细")
public String getUser(@RequestParam("id") Integer id) {
return "DEMO:" + id;
}
@PostMapping("/create")
@SoulClient(path = "/user/create", desc = "创建用户")
public Integer createUser(@RequestBody UserCreateDTO createDTO) {
logger.info("[createUser][username({}) password({})]", createDTO.getNickname(), createDTO.getGender());
return 1;
}
}
@SoulClient
注解一共有三个属性:
path
:映射的 HTTP 接口的请求路径。
desc
:接口的描述,便于知道其用途。
enable
:是否开启,默认为 true
开启。
后续,在 Spring Cloud 应用启动时,Soul Client 会自动解析 @SoulClient
注解的 API 方法,写入方法的元数据到 Soul Admin 控制台,最终通知到 Soul Bootstrap 服务网关上。
① 执行 DemoApplication 启动 Spring Boot 应用。在 IDEA 控制台可以看到如下日志,看到写入 HTTP API 方法的元数据到 Soul Admin 控制台。
2020-05-23 17:00:26.711 INFO 67422 --- [pool-1-thread-1] s.SoulSpringCloudClientBeanPostProcessor : springCloud client register success :{} {"appName":"sc-user-service","path":"/sc-user-service-api/user/get","pathDesc":"获得用户详细","rpcType":"springCloud","serviceName":"UserController","methodName":"getUser","parameterTypes":"java.lang.Integer","rpcExt":"","enabled":true}
2020-05-23 17:00:27.110 INFO 67422 --- [pool-1-thread-1] s.SoulSpringCloudClientBeanPostProcessor : springCloud client register success :{} {"appName":"sc-user-service","path":"/sc-user-service-api/user/create","pathDesc":"创建用户","rpcType":"springCloud","serviceName":"UserController","methodName":"createUser","parameterTypes":"cn.iocoder.springcloud.lab60.dto.UserCreateDTO","rpcExt":"","enabled":true}
② 使用浏览器,访问 http://127.0.0.1:9095/#/system/metadata 地址,进入「系统管理 -> 元数据」菜单,可以看到上述注册的元数据。如下图所示:
系统管理 -> 元数据③ 使用浏览器,访问 http://127.0.0.1:9095/#/plug/divide 地址,进入「插件列表 -> Divide」菜单,看到选择器和规则。如下图所示:
插件列表 -> springcloud点击选择器 /sc-user-service-api
的「编辑」按钮,查看该选择器的具体信息。如下图所示:
点击规则 /sc-user-service-api/user/get
的「编辑」按钮,查看该规则的具体信息。如下图所示:
④ 使用 Postman 模拟请求 http://127.0.0.1:9195/sc-user-service-api/user/get?id=1 地址,转发到 GET /user/get
接口上。如下图所示:
使用 Request Method 为 GET
。
请求参数,直接带在 URL 后面。
⑤ 使用 Postman 模拟请求 http://127.0.0.1:9195/sb-demo-api/user/create 地址,转发到 POST /user/create
接口上。如下图所示:
使用 Request Method 为 POST
。
请求内容类型为 application/json
。
因为 POST /user/create
使用 JSON 接参,所以直接在 Request Body 输入 JSON 数据格式。
至此,我们已经完成了 Soul 网关接入 Spring Cloud 应用,并进行相应的而测试。
友情提示:实际上,我们也可以参考《Soul 文档 —— springcloud 插件》,手动在 Soul Admin 控制台配置 API 接口方法的元数据,以及进行 springcloud 插件的选择器和规则的设置,实现 Soul Bootstrap 服务网关转发请求到 Spring Cloud 应用,无需在 Spring Cloud 应用中引入
soul-client-springcloud
依赖。也就是说,引入
soul-client-springcloud
依赖的目的,是为了实现自动化,毕竟手工配置比较麻烦,并且容易出错。
本小节,我们参考《Soul 文档 —— rateLimiter 插件》文章,使用 rateLimiter 插件,实现 Soul 网关的限流功能。该插件是基于令牌桶算法 + Redis 存储计数,实现分布式限流。整体设计如下图:
原理下面,我们在「3. 接入 Dubbo 应用」小节的基础上,对 user-api/user/get
实现限流的功能。
相信大家都会,艿艿就不瞎哔哔了。嘿嘿~
先需要设置 rateLimiter 插件 的 Redis 配置,目前支持单机、哨兵、集群模式。
① 使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 rateLimiter 插件。如下图所示:
系统管理 -> 插件管理② 点击 rateLimiter 插件的「编辑」按钮,设置 Redis 的配置,并设置该插件为开启。如下图所示:
系统管理 -> 插件管理 -> 编辑友情提示:Redis 的地址,记得要填写正确哈~
③ 因为 Soul Bootstrap 和 Soul Admin 暂时不支持插件修改的自动加载,所以我们此时需要手动重启下。
① 使用浏览器,访问 http://127.0.0.1:9095/#/plug/rate_limiter 地址,进入「插件列表 -> rate_limiter」菜单,进行限流规则的配置。如下图所示:
插件列表 -> rate_limiter② 点击「添加选择器」按钮,添加一个选择器。如下图所示:
插件列表 -> rate_limiter -> 添加选择器③ 点击「添加规则」按钮,给该选择器添加一个规则。如下图所示:
插件列表 -> rate_limiter -> 添加规则对请求地址 /user-api/user/get
进行限流,对应 UserService 的 #getUser(Integer id)
方法。
速率:是你允许用户每秒执行多少请求,而丢弃任何请求。这是令牌桶的填充速率。
容量:是允许用户在一秒钟内执行的最大请求数。这是令牌桶可以保存的令牌数。
友情提示:可能胖友对 Soul 定义的选择器与规则的概念有点不了解,可以看看《Soul 文档 —— 选择器规则详解》文章。
执行 UserServiceApplication 启动 Dubbo 服务。
快速且多次使用 Postman 模拟请求 http://127.0.0.1:9195/user-api/user/get 地址,调用 UserServiceImpl#getUser(Integer id)
方法,最终被限流。如下图所示:
本小节,我们参考《Soul 文档 —— hystrix 插件》文章,使用 hystrix 插件,使用 Hystrix 框架,实现 Soul 网关的熔断器功能。
友情提示:对 Hystrix 不了解的胖友,可以后续阅读《芋道 Spring Boot 服务容错 Hystrix 入门》文章进行学习。
下面,我们在「3. 接入 Dubbo 应用」小节的基础上,对 user-api/user/get
实现熔断器的功能。
需要设置 hystrix 插件 为开启。
使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 hystrix 插件。如下图所示:
系统管理 -> 插件管理默认情况下,hystrix 插件已经是开启状态,所以无需开启。
① 使用浏览器,访问 http://127.0.0.1:9095/#/plug/hystrix 地址,进入「插件列表 -> hystrix」菜单,进行熔断器规则的配置。如下图所示:
插件列表 -> hystrix② 点击「添加选择器」按钮,添加一个选择器。如下图所示:
插件列表 -> hystrix -> 添加选择器③ 点击「添加规则」按钮,给该选择器添加一个规则。如下图所示:
插件列表 -> hystrix -> 添加规则对请求地址 /user-api/user/get
进行熔断保护,对应 UserService 的 #getUser(Integer id)
方法。
友情提示:可能胖友对 Soul 定义的选择器与规则的概念有点不了解,可以看看《Soul 文档 —— 选择器规则详解》文章。
不要执行 UserServiceApplication 启动 Dubbo 服务,模拟其故障。
快速且多次使用 Postman 模拟请求 http://127.0.0.1:9195/user-api/user/get 地址,调用 UserServiceImpl#getUser(Integer id)
方法,最终被熔断。如下图所示:
此时,我们在 Soul Bootstrap 网关的日志可以看到,Hystrix 熔断器已经打开。日志内容如下:
2020-05-23 20:52:28.786 ERROR 69264 --- [work-threads-20] o.d.s.web.plugin.hystrix.HystrixPlugin : hystrix execute have circuitBreaker is Open! groupKey:user-service,commandKey:cn.iocoder.springboot.lab60.userservice.api.UserService
至此,我们已经完成了 Soul 网关的学习,后续胖友可以阅读《Soul 文档》,了解本文暂时并未写到的内容。
例如插件相关:
monitor 插件:实现监控数据的收集,后续可以使用 Grafana 实现监控仪表盘。
waf 插件:实现黑名单功能,禁止恶意 IP 的访问。
sign 插件:实现请求签名功能,保证接口的安全性。
rewrite 插件:对请求 URI 进行重写。
websocket 插件:实现对 Websocket 进行代理转发。
自定义插件:自己实现插件,进一步拓展自己的插件。
例如功能相关:
自定义 filter:自定义 Filter,可以拓展安全认证等等功能。
文件上传下载:提供的文件上传和下载功能。
友情提示:建议文件上传不要经过 API 网关,而是先上传到文件服务器,然后提交 URL 到 API 网关。
自定义 host 与 ip:考虑到 API 网关的前面都有 Nginx,所以需要拓展保证解析到正确的用户 IP。
自定义返回结果:每个公司的统一返回格式可能有差异,最好自己拓展下。
欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:
已在知识星球更新源码解析如下:
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。
提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
兄弟,艿一口,点个赞!????