又一國產微服務網關 Soul,一起來肝一肝,Dubbo、SpringCloud、SpringBoot 全支持!...

點擊上方“芋道源碼”,選擇“設爲星標

管她前浪,還是後浪?

能浪的浪,纔是好浪!

每天 8:55 更新文章,每天掉億點點頭髮...

源碼精品專欄

 

摘要: 原創出處 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 網關。

2. 單機部署

本小節,我們來單機部署一個 Soul 服務,適合測試環境。如下圖所示:

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 數據庫

友情提示:具體的數據庫設計,後續可以看看《Soul 文檔 —— 數據庫設計》。

③ 啓動完成後,我們可以通過日誌看到 Soul Admin 啓動在 9095 端口。使用瀏覽器,訪問 http://127.0.0.1:9095/ 地址,進入登錄頁。

Soul Admin - 登錄頁

默認內置管理員賬號「admin/123456」。輸入賬號密碼,進入首頁。

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 服務網關。整個示例架構如下圖所示:

示例的整體架構

下面,我們來開始正式接入 Dubbo 應用。

3.1 設置 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 暫時不支持插件修改的自動加載,所以我們此時需要手動重啓下。

3.2 搭建 Dubbo 示例項目

先快速搭建一個 Dubbo 示例項目,暫未接入 Soul 網關。如下圖所示:

項目結構
  • 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 的集成支持。

<!-- 引入 Soul 針對 Dubbo 的集成的依賴 -->
<dependency>
    <groupId>org.dromara</groupId>
    <artifactId>soul-client-apache-dubbo</artifactId>
    <version>2.1.2-RELEASE</version>
</dependency>

友情提示:如果胖友使用 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 地址,進入「系統管理 -> 元數據」菜單,可以看到上述註冊的元數據。如下圖所示:

系統管理 -> 元數據

③ 使用瀏覽器,訪問 http://127.0.0.1:9095/#/plug/dubbo 地址,進入「插件列表 -> Dubbo」菜單,看到選擇器規則。如下圖所示:

插件列表 -> Dubbo

點擊選擇器 /user-api 的「編輯」按鈕,查看該選擇器的具體信息。如下圖所示:

插件列表 -> Dubbo -> 選擇器

點擊規則 /user-api/user/get 的「編輯」按鈕,查看該規則的具體信息。如下圖所示:

插件列表 -> Dubbo -> 規則

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

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) 方法。如下圖所示:

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 服務網關。整個示例架構如下圖所示:

示例的整體架構

下面,我們來開始正式接入 Spring Boot 應用。

4.1 設置 divide 插件

需要設置 divide 插件 爲開啓。該插件實現 HTTP 正向代理的功能,所有 HTTP 類型的請求你,都由它進行負載均衡的調用。

使用瀏覽器,訪問 http://127.0.0.1:9095/#/system/plugin 地址,進入「系統管理 -> 插件管理」菜單,可以看到 divide 插件。如下圖所示:

系統管理 -> 插件管理

默認情況下,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 網關。如下圖所示:

項目結構
  • lab-60-soul-spring-boot-demo

4.3.1 引入依賴

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

<!-- 引入 Soul 針對 SpringMVC 的集成的依賴 -->
<dependency>
    <groupId>org.dromara</groupId>
    <artifactId>soul-client-springmvc</artifactId>
    <version>2.1.2-RELEASE</version>
</dependency>

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 地址,進入「系統管理 -> 元數據」菜單,可以看到上述註冊的元數據。如下圖所示:

系統管理 -> 元數據

③ 使用瀏覽器,訪問 http://127.0.0.1:9095/#/plug/divide 地址,進入「插件列表 -> Divide」菜單,看到選擇器規則。如下圖所示:

插件列表 -> Divide

點擊選擇器 /sb-demo-api 的「編輯」按鈕,查看該選擇器的具體信息。如下圖所示:

插件列表 -> Divide -> 選擇器

點擊規則 /sb-demo-api/user/get 的「編輯」按鈕,查看該規則的具體信息。如下圖所示:

插件列表 -> Divide -> 規則

④ 使用 Postman 模擬請求 http://127.0.0.1:9195/sb-demo-api/user/get?id=1 地址,轉發到 GET /user/get 接口上。如下圖所示:

Postman 模擬
  • 使用 Request MethodGET

  • 請求參數,直接帶在 URL 後面。

⑤ 使用 Postman 模擬請求 http://127.0.0.1:9195/sb-demo-api/user/create 地址,轉發到 POST /user/create 接口上。如下圖所示:

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 服務網關。整個示例架構如下圖所示:

示例的整體架構

下面,我們來開始正式接入 Spring Cloud 應用。

5.1 設置 springcloud 插件

需要設置 springcloud 插件 爲開啓。該插件實現從 Spring Cloud 註冊中心獲取服務的示例列表,後續使用 Ribbon 實現負載均衡的調用。

使用瀏覽器,訪問 http://127.0.0.1:9095/#/system/plugin 地址,進入「系統管理 -> 插件管理」菜單,可以看到 springcloud 插件。如下圖所示:

系統管理 -> 插件管理

默認情況下,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 源碼

② 修改 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,可以暫時忽略。

5.4 搭建 Spring Cloud 示例項目

先快速搭建一個 Spring Cloud 示例項目,暫未接入 Soul 網關。如下圖所示:

項目結構
  • lab-60-soul-spring-cloud-demo

5.4.1 引入依賴

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

<!-- 引入 Soul 針對 Spring Cloud 的集成的依賴 -->
<dependency>
    <groupId>org.dromara</groupId>
    <artifactId>soul-client-springcloud</artifactId>
    <version>2.1.2-RELEASE</version>
</dependency>

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 地址,進入「系統管理 -> 元數據」菜單,可以看到上述註冊的元數據。如下圖所示:

系統管理 -> 元數據

③ 使用瀏覽器,訪問 http://127.0.0.1:9095/#/plug/divide 地址,進入「插件列表 -> Divide」菜單,看到選擇器規則。如下圖所示:

插件列表 -> springcloud

點擊選擇器 /sc-user-service-api 的「編輯」按鈕,查看該選擇器的具體信息。如下圖所示:

插件列表 -> springcloud -> 選擇器

點擊規則 /sc-user-service-api/user/get 的「編輯」按鈕,查看該規則的具體信息。如下圖所示:

插件列表 -> Divide -> 規則

④ 使用 Postman 模擬請求 http://127.0.0.1:9195/sc-user-service-api/user/get?id=1 地址,轉發到 GET /user/get 接口上。如下圖所示:

Postman 模擬
  • 使用 Request MethodGET

  • 請求參數,直接帶在 URL 後面。

⑤ 使用 Postman 模擬請求 http://127.0.0.1:9195/sb-demo-api/user/create 地址,轉發到 POST /user/create 接口上。如下圖所示:

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 存儲計數,實現分佈式限流。整體設計如下圖:

原理

下面,我們在「3. 接入 Dubbo 應用」小節的基礎上,對 user-api/user/get 實現限流的功能。

6.1 安裝 Redis

相信大家都會,艿艿就不瞎嗶嗶了。嘿嘿~

6.2 設置 rateLimiter 插件

先需要設置 rateLimiter 插件 的 Redis 配置,目前支持單機、哨兵、集羣模式。

① 使用瀏覽器,訪問 http://127.0.0.1:9095/#/system/plugin 地址,進入「系統管理 -> 插件管理」菜單,可以看到 rateLimiter 插件。如下圖所示:

系統管理 -> 插件管理

② 點擊 rateLimiter 插件的「編輯」按鈕,設置 Redis 的配置,並設置該插件爲開啓。如下圖所示:

系統管理 -> 插件管理 -> 編輯

友情提示:Redis 的地址,記得要填寫正確哈~

③ 因爲 Soul Bootstrap 和 Soul Admin 暫時不支持插件修改的自動加載,所以我們此時需要手動重啓下。

6.3 設置 rateLimiter 限流規則

① 使用瀏覽器,訪問 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 文檔 —— 選擇器規則詳解》文章。

6.4 簡單測試

執行 UserServiceApplication 啓動 Dubbo 服務。

快速多次使用 Postman 模擬請求 http://127.0.0.1:9195/user-api/user/get 地址,調用 UserServiceImpl#getUser(Integer id) 方法,最終被限流。如下圖所示:

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 插件。如下圖所示:

系統管理 -> 插件管理

默認情況下,hystrix 插件已經是開啓狀態,所以無需開啓。

7.2 設置 rateLimiter 限流規則

① 使用瀏覽器,訪問 http://127.0.0.1:9095/#/plug/hystrix 地址,進入「插件列表 -> hystrix」菜單,進行熔斷器規則的配置。如下圖所示:

插件列表 -> hystrix

② 點擊「添加選擇器」按鈕,添加一個選擇器。如下圖所示:

插件列表 -> hystrix -> 添加選擇器

③ 點擊「添加規則」按鈕,給該選擇器添加一個規則。如下圖所示:

插件列表 -> 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) 方法,最終被熔斷。如下圖所示:

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 領取,更多內容陸續奉上。

兄弟,一口,點個????

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章