又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!...

点击上方“芋道源码”,选择“设为星标”

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 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. 彩蛋


1. 概述

Soul 是基于 WebFlux 实现的响应式的 API 网关,具有异步、高性能、跨语言等特点。

作者:我希望能够有一样东西像灵魂一样,保护您的微服务。在参考了 Kong、Spring Cloud Gateway 等优秀的网关后,站在巨人的肩膀上,Soul 由此诞生!

作者是艿艿的大表弟,胖友信么?!

目前 Soul 功能列表如下:

  • 支持各种语言,无缝集成到 Dubbo、Spring Cloud、Spring Boot 中。

    Soul 是极其少支持 Dubbo 的 API 网关,通过 Dubbo 泛化调用 实现。

  • 丰富的插件支持,鉴权,限流,熔断,防火墙等等。

  • 网关多种规则动态配置,支持各种策略配置。

  • 插件热插拔,易扩展。

  • 支持集群部署,支持 A/B Test。

整体架构如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第1张图片 架构图

是不是看着就贼酷炫,实际一脸懵逼。不要慌~我们先来搭建 Soul 网关。

2. 单机部署

本小节,我们来单机部署一个 Soul 服务,适合测试环境。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第2张图片 Soul 单机部署

2.1 MySQL 安装

相信大家都会,艿艿就不瞎哔哔了。嘿嘿~注意,目前最好安装 5.X 版本,艿艿一开始用 8.X 存在报错的情况。

安装完成后,创建 soul 数据库。

2.2 Soul Admin 安装

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,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第3张图片 soul 数据库

友情提示:具体的数据库设计,后续可以看看《Soul 文档 —— 数据库设计》。

③ 启动完成后,我们可以通过日志看到 Soul Admin 启动在 9095 端口。使用浏览器,访问 http://127.0.0.1:9095/ 地址,进入登录页。

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第4张图片 Soul Admin - 登录页

默认内置管理员账号「admin/123456」。输入账号密码,进入首页。

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第5张图片 Soul Admin - 首页

胖友可以自己随便点点,简单了解下有哪些功能。

2.3 Soul Bootstrap 安装

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
}

2.4 下一步

至此,我们已经完成了 Soul 服务的单机部署,是不是挺简单的。下面,胖友可以根据自己的需要,阅读如下小节:

  • 「3. 接入 Dubbo 应用」

  • 「4. 接入 Spring Boot 应用」

  • 「5. 接入 Spring Cloud 应用」

3. 接入 Dubbo 应用

示例代码对应仓库:lab-60-soul-dubbo-demo-user-service

本小节,我们参考《Soul 文档 —— Dubbo 用户接入》文章,接入 Soul 服务网关。整个示例架构如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第6张图片 示例的整体架构

下面,我们来开始正式接入 Dubbo 应用。

3.1 设置 dubbo 插件

先需要设置 dubbo 插件 的注册中心,因为 Soul Bootstrap 服务网关需要从注册中心获取到 Dubbo 服务的实例列表。

① 使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 dubbo 插件。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第7张图片 系统管理 -> 插件管理

② 点击 dubbo 插件的「编辑」按钮,设置注册中心的配置。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第8张图片 系统管理 -> 插件管理 -> 编辑
  • 因为我们将使用 Nacos 作为 Dubbo 服务的注册中心,所以这里设置为 {"register":"nacos://localhost:8848"}

  • 如果胖友使用 Zookeeper 作为 Dubbo 服务的注册中心,所以这里设置为 {"register":"zookeeper://localhost:2181"}

友情提示:注册中心的地址,记得要填写正确哈~

③ 因为 Soul Bootstrap 和 Soul Admin 暂时不支持插件修改的自动加载,所以我们此时需要手动重启下。

3.2 搭建 Dubbo 示例项目

先快速搭建一个 Dubbo 示例项目,暂未接入 Soul 网关。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第9张图片 项目结构
  • lab-60-soul-dubbo-demo-user-service-api

  • lab-60-soul-dubbo-demo-user-service

友情提示:如果胖友对 Dubbo + Nacos 不了解的胖友,可以阅读《芋道 Spring Boot Dubbo 入门》文章。

下面,我们来将它改造接入 Soul 网关。

3.2.1 引入依赖

修改 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 依赖。

3.2.2 配置文件

修改 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 配置类。具体每个配置项的作用,胖友自己看配置项后的注释。

3.2.3 UserServiceImpl

需要在 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 服务网关上。

3.3 简单测试

① 执行 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 地址,进入「系统管理 -> 元数据」菜单,可以看到上述注册的元数据。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第10张图片 系统管理 -> 元数据

③ 使用浏览器,访问 http://127.0.0.1:9095/#/plug/dubbo 地址,进入「插件列表 -> Dubbo」菜单,看到选择器规则。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第11张图片 插件列表 -> Dubbo

点击选择器 /user-api 的「编辑」按钮,查看该选择器的具体信息。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第12张图片 插件列表 -> Dubbo -> 选择器

点击规则 /user-api/user/get 的「编辑」按钮,查看该规则的具体信息。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第13张图片 插件列表 -> Dubbo -> 规则

④ 使用 Postman 模拟请求 http://127.0.0.1:9195/user-api/user/get 地址,调用 UserServiceImpl#getUser(Integer id) 方法。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第14张图片 Postman 模拟
  • 使用 Request MethodPOST

  • 请求内容类型为 application/json

  • 因为 UserServiceImpl#getUser(Integer id) 方法是非 Bean 参数类型,所以直接在 Request Body 输入具体值即可。

⑤ 使用 Postman 模拟请求 http://127.0.0.1:9195/user-api/user/create 地址,调用 UserServiceImpl#createUser(UserCreateDTO createDTO) 方法。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第15张图片 Postman 模拟
  • 使用 Request MethodPOST

  • 请求内容类型为 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 依赖的目的,是为了实现自动化,毕竟手工配置比较麻烦,并且容易出错。

4. 接入 Spring Boot 应用

示例代码对应仓库:lab-60-soul-spring-boot-demo

本小节,我们参考《Soul 文档 —— http 用户接入》文章,接入 Soul 服务网关。整个示例架构如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第16张图片 示例的整体架构

下面,我们来开始正式接入 Spring Boot 应用。

4.1 设置 divide 插件

需要设置 divide 插件 为开启。该插件实现 HTTP 正向代理的功能,所有 HTTP 类型的请求你,都由它进行负载均衡的调用。

使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 divide 插件。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第17张图片 系统管理 -> 插件管理

默认情况下,divide 插件已经是开启状态,所以无需开启。

4.2 安装 Zookeeper

因为 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

4.3 搭建 Spring Boot 示例项目

先快速搭建一个 Spring Boot 示例项目,暂未接入 Soul 网关。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第18张图片 项目结构
  • lab-60-soul-spring-boot-demo

4.3.1 引入依赖

修改 pom.xml 文件,引入 soul-client-springmvc 依赖,它是 Soul 对 SpringMVC 的集成支持。



    org.dromara
    soul-client-springmvc
    2.1.2-RELEASE

4.3.2 配置文件

修改 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 配置类。具体每个配置项的作用,胖友自己看配置项后的注释。

4.3.3 UserController

需要在 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 服务网关上。

4.4 简单测试

① 执行 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 地址,进入「系统管理 -> 元数据」菜单,可以看到上述注册的元数据。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第19张图片 系统管理 -> 元数据

③ 使用浏览器,访问 http://127.0.0.1:9095/#/plug/divide 地址,进入「插件列表 -> Divide」菜单,看到选择器规则。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第20张图片 插件列表 -> Divide

点击选择器 /sb-demo-api 的「编辑」按钮,查看该选择器的具体信息。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第21张图片 插件列表 -> Divide -> 选择器

点击规则 /sb-demo-api/user/get 的「编辑」按钮,查看该规则的具体信息。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第22张图片 插件列表 -> Divide -> 规则

④ 使用 Postman 模拟请求 http://127.0.0.1:9195/sb-demo-api/user/get?id=1 地址,转发到 GET /user/get 接口上。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第23张图片 Postman 模拟
  • 使用 Request MethodGET

  • 请求参数,直接带在 URL 后面。

⑤ 使用 Postman 模拟请求 http://127.0.0.1:9195/sb-demo-api/user/create 地址,转发到 POST /user/create 接口上。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第24张图片 Postman 模拟
  • 使用 Request MethodPOST

  • 请求内容类型为 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 中手动维护应用的实例列表,会比较麻烦~

5. 接入 Spring Cloud 应用

示例代码对应仓库:lab-60-soul-spring-cloud-demo

本小节,我们参考《Soul 文档 —— springcloud 用户接入》文章,接入 Soul 服务网关。整个示例架构如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第25张图片 示例的整体架构

下面,我们来开始正式接入 Spring Cloud 应用。

5.1 设置 springcloud 插件

需要设置 springcloud 插件 为开启。该插件实现从 Spring Cloud 注册中心获取服务的示例列表,后续使用 Ribbon 实现负载均衡的调用。

使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 springcloud 插件。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第26张图片 系统管理 -> 插件管理

默认情况下,springcloud 插件已经是开启状态,所以无需开启。

5.2 安装 Nacos

我们使用 Nacos 作为 Spring Cloud 应用的注册中心,所有胖友可以参照《Nacos 极简入门》文章,搭建一个 Nacos 注册中心。

友情提示:如果想要 Eureka 作为 Spring Cloud 应用注册中心的胖友,可以参照《芋道 Spring Cloud Netflix 注册中心 Eureka 入门》文章,搭建一个 Eureka 注册中心。

5.3 修改 Soul Bootstrap 接入 Nacos

因为 Soul Bootstrap 需要从注册中心获取 Spring Cloud 应用的实例列表,所以需要集成 Spring Cloud 注册中心。目前,默认情况下 Soul Bootstrap 网关服务提供的 soul-bootstrap.jar 包,并未引入相关依赖,所以我们需要自己修改源码,并进行打包。

① 使用 IDEA 从 https://gitee.com/shuaiqiyu/soul 仓库中,下载最新的源码。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第27张图片 soul 源码

② 修改 application.yml 配置文件,添加 spring.cloud.nacos.discovery.server-addr 配置项为 Nacos 注册中心的地址。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第28张图片 application.yml 配置文件

③ 修改 pom.xml 文件,引入 spring-cloud-starter-alibaba-nacos-discovery 依赖,集成 Nacos 作为 Spring Cloud 的注册中心。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第29张图片 pom.xml 文件

友情提示:如果想要 Eureka 作为 Spring Cloud 应用注册中心的胖友,也是修改配置文件,和引入依赖。

④ 关闭 soul-bootstrap.jar 启动的服务网关,在 IDEA 中执行 SoulBootstrapApplication 启动服务网关。美滋滋~

友情提示:启动时,会报 Connection refused: localhost/127.0.0.1:6379 错误,这是 Soul 限流功能需要使用到 Redis,可以暂时忽略。

5.4 搭建 Spring Cloud 示例项目

先快速搭建一个 Spring Cloud 示例项目,暂未接入 Soul 网关。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第30张图片 项目结构
  • lab-60-soul-spring-cloud-demo

5.4.1 引入依赖

修改 pom.xml 文件,引入 soul-client-springcloud 依赖,它是 Soul 对 Spring Cloud 的集成支持。



    org.dromara
    soul-client-springcloud
    2.1.2-RELEASE

5.4.2 配置文件

修改 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 配置类。具体每个配置项的作用,胖友自己看配置项后的注释。

5.4.3 UserController

需要在 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 服务网关上。

5.5 简单测试

① 执行 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 地址,进入「系统管理 -> 元数据」菜单,可以看到上述注册的元数据。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第31张图片 系统管理 -> 元数据

③ 使用浏览器,访问 http://127.0.0.1:9095/#/plug/divide 地址,进入「插件列表 -> Divide」菜单,看到选择器规则。如下图所示:

插件列表 -> springcloud

点击选择器 /sc-user-service-api 的「编辑」按钮,查看该选择器的具体信息。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第32张图片 插件列表 -> springcloud -> 选择器

点击规则 /sc-user-service-api/user/get 的「编辑」按钮,查看该规则的具体信息。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第33张图片 插件列表 -> Divide -> 规则

④ 使用 Postman 模拟请求 http://127.0.0.1:9195/sc-user-service-api/user/get?id=1 地址,转发到 GET /user/get 接口上。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第34张图片 Postman 模拟
  • 使用 Request MethodGET

  • 请求参数,直接带在 URL 后面。

⑤ 使用 Postman 模拟请求 http://127.0.0.1:9195/sb-demo-api/user/create 地址,转发到 POST /user/create 接口上。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第35张图片 Postman 模拟
  • 使用 Request MethodPOST

  • 请求内容类型为 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 依赖的目的,是为了实现自动化,毕竟手工配置比较麻烦,并且容易出错。

6. rateLimiter 插件

本小节,我们参考《Soul 文档 —— rateLimiter 插件》文章,使用 rateLimiter 插件,实现 Soul 网关的限流功能。该插件是基于令牌桶算法 + Redis 存储计数,实现分布式限流。整体设计如下图:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第36张图片 原理

下面,我们在「3. 接入 Dubbo 应用」小节的基础上,对 user-api/user/get 实现限流的功能。

6.1 安装 Redis

相信大家都会,艿艿就不瞎哔哔了。嘿嘿~

6.2 设置 rateLimiter 插件

先需要设置 rateLimiter 插件 的 Redis 配置,目前支持单机、哨兵、集群模式。

① 使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 rateLimiter 插件。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第37张图片 系统管理 -> 插件管理

② 点击 rateLimiter 插件的「编辑」按钮,设置 Redis 的配置,并设置该插件为开启。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第38张图片 系统管理 -> 插件管理 -> 编辑

友情提示:Redis 的地址,记得要填写正确哈~

③ 因为 Soul Bootstrap 和 Soul Admin 暂时不支持插件修改的自动加载,所以我们此时需要手动重启下。

6.3 设置 rateLimiter 限流规则

① 使用浏览器,访问 http://127.0.0.1:9095/#/plug/rate_limiter 地址,进入「插件列表 -> rate_limiter」菜单,进行限流规则的配置。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第39张图片 插件列表 -> rate_limiter

② 点击「添加选择器」按钮,添加一个选择器。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第40张图片 插件列表 -> rate_limiter -> 添加选择器

③ 点击「添加规则」按钮,给该选择器添加一个规则。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第41张图片 插件列表 -> rate_limiter -> 添加规则
  • 对请求地址 /user-api/user/get 进行限流,对应 UserService 的 #getUser(Integer id) 方法。

  • 速率:是你允许用户每秒执行多少请求,而丢弃任何请求。这是令牌桶的填充速率。

  • 容量:是允许用户在一秒钟内执行的最大请求数。这是令牌桶可以保存的令牌数。

友情提示:可能胖友对 Soul 定义的选择器规则的概念有点不了解,可以看看《Soul 文档 —— 选择器规则详解》文章。

6.4 简单测试

执行 UserServiceApplication 启动 Dubbo 服务。

快速多次使用 Postman 模拟请求 http://127.0.0.1:9195/user-api/user/get 地址,调用 UserServiceImpl#getUser(Integer id) 方法,最终被限流。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第42张图片 Postman 模拟

7. hystrix 插件

本小节,我们参考《Soul 文档 —— hystrix 插件》文章,使用 hystrix 插件,使用 Hystrix 框架,实现 Soul 网关的熔断器功能。

友情提示:对 Hystrix 不了解的胖友,可以后续阅读《芋道 Spring Boot 服务容错 Hystrix 入门》文章进行学习。

下面,我们在「3. 接入 Dubbo 应用」小节的基础上,对 user-api/user/get 实现熔断器的功能。

7.1 设置 hystrix 插件

需要设置 hystrix 插件 为开启

使用浏览器,访问 http://127.0.0.1:9095/#/system/plugin 地址,进入「系统管理 -> 插件管理」菜单,可以看到 hystrix 插件。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第43张图片 系统管理 -> 插件管理

默认情况下,hystrix 插件已经是开启状态,所以无需开启。

7.2 设置 rateLimiter 限流规则

① 使用浏览器,访问 http://127.0.0.1:9095/#/plug/hystrix 地址,进入「插件列表 -> hystrix」菜单,进行熔断器规则的配置。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第44张图片 插件列表 -> hystrix

② 点击「添加选择器」按钮,添加一个选择器。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第45张图片 插件列表 -> hystrix -> 添加选择器

③ 点击「添加规则」按钮,给该选择器添加一个规则。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第46张图片 插件列表 -> hystrix -> 添加规则
  • 对请求地址 /user-api/user/get 进行熔断保护,对应 UserService 的 #getUser(Integer id) 方法。

友情提示:可能胖友对 Soul 定义的选择器规则的概念有点不了解,可以看看《Soul 文档 —— 选择器规则详解》文章。

7.3 简单测试

不要执行 UserServiceApplication 启动 Dubbo 服务,模拟其故障

快速多次使用 Postman 模拟请求 http://127.0.0.1:9195/user-api/user/get 地址,调用 UserServiceImpl#getUser(Integer id) 方法,最终被熔断。如下图所示:

又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!..._第47张图片 Postman 模拟

此时,我们在 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

666. 彩蛋

至此,我们已经完成了 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 领取,更多内容陆续奉上。

兄弟,一口,点个????

你可能感兴趣的:(又一国产微服务网关 Soul,一起来肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!...)