歡迎光臨
每天分享高質量文章

推薦一個微服務網關,支持 Dubbo、Spring Cloud、Spring Boot !

Soul網關由來?

Soul網關是我在任職某大型電商公司中間件技術部的時候所開發的。開源以後,針對不同的用戶需求,進行了功能的升級,比如 支持了springcloud websocket restful風格 get請求,插件可以定製化開發等等,感謝開源。

當時我們面對什麼問題呢?

  • 首先公司有很多語言,java,net,php,Python等等,相互之間的交互只能通過http,呼叫很不統一,尤其是java為主以後,php等語言要呼叫dubbo服務,dubbo服務者必須提供http服務出來,增加了java後端人員的工作量。
  • 接口鑒權,限流,代理等等很多基本的需求,如果由每個業務系統開發人員開發,增加了成本,風險不可控。
  • 所有的配置沒有統一化的管理頁面,不利於管理。
  • 接口的性能沒有監控,不利於橫向擴展。
  • 業務系統進行灰度發佈,需要運維進行nginx負載,增加了運維的工作量。
  • 等等很多很多的因素,我們需要一個可配置的,可視化,高性能的API網關,做為公司的公用服務。

當時我們怎麼解決的呢?

首先我們調研了市場上的一些API網關 zuul kong sc-gateway

  • zuul 是一個中間件產品,完全可以由業務系統自己去引入,性能沒達到我們的預期,沒有動態化的配置,不利於管理,和我們中間件技術部好像沒啥關係。

  • kong kong確實是好,好到它的某些功能是收費的,而且它是lua語言開發,維護成本太高(其實就是hold不住lua)

  • sc-gateway 這個是基於webflux的,底層也是基於netty,性能可以,其缺點就是,沒有動態化的配置,而且也只是sc-cloud體系的,其他的業務系統怎麼接入? 怎麼做成公用服務?每次新上接口怎麼辦?動態調整接口的限流速率怎麼辦?等等很多問題。

so 基於以上問題,我們綜合考慮,決定自己乾一個。我在做的時候,參考了kong的插件思想,sc-gateway的webflux思想,再結合公司的定製需求寫出了soul網關.

首先我們來看一張soul的架構圖,有利於加深它的運行原理

  • 首先別被這張圖嚇著,我來詳細的講解下,綠色的部分,客戶端就是代表用戶,它按照網關要求的資料格式來請求網關服務。

  • soul服務其實就是個http服務,底層用了webflux,所以它如果部署集群的話,可以開啟一個nginx集群,來反向代理soul服務

  • soul-admin 就是整個soul的整個管理後臺,它配置所有的規則選擇器,然後再把資料寫到zookeeper。

  • soul服務在啟動的時候,會拉取zookeeper的資料,寫到本地JVM,然後繼續監聽 zookeeper,來動態更新JVM中的資料,這一塊 可以參考 zookeeper-node 設計。

  • 後面就是soul的執行流程了,基本上就是插件責任鏈樣式,具體的插件執行具體的事情. 每個插件它是根據用戶請求網關的資料,與admin後臺配置的規則,來執行具體的邏輯。所以這有個很重要的東西,用戶訪問soul的資料請求格式是什麼?

我們來看一下soul實現的功能

  • 自帶插件: 防火牆,簽名,監控,限流,代理,dubbo,springcloud
  • 所有的插件,選擇器,規則,熱插拔,動態配置。
  • 無縫對接http,restful,websocket,dubbo,springcloud 等協議
  • 支持集群部署,支持灰度發佈。
  • 當然你熟了以後,還有很多其他的功能,比如查找定位問題,A/B test 等等

請求soul網關

  • 這裡我假設你已經部署好了soul-admin 以及 soul-web 為localhost:8080
  • 你使用 http工具類,或者postman ,post請求訪問 localhost:8080
  • http essay-header 頭設置:
  1. module :必填,指請求的系統模塊,建議:所有插件的選擇器中應該根據此欄位來匹配
  2. method :必填,請求的方法,指真實請求的方法,如果是http/springcloud,那麼指請求的方法路徑。如果是dubbo,那就是請求的真實方法. 建議:所有插件規則應該根據此欄位來匹配過濾請求
    1. rpcType: 請求的型別,填寫http 則會使用divide插件,填寫dubbo則會使用dubbo插件,填寫springcloud則會使用springcloud插件。
    2. 這裡我只有列舉了比較簡單的幾個欄位,還有幾個欄位未寫,可以在這裡看:請求引數設置

這裡就有一個大體的印象,我是用http訪問了soul網關,只不過在http essay-header裡面新增了幾個soul需要的幾個欄位而已。

當然如果你比較熟悉soul的話,這裡是非常寬泛的,用戶完全可以自己傳遞欄位,然後在admin後來,根據欄位來匹配就好了,相當靈活便利

接下來我們來熟悉下:插件 選擇器 規則

話不多說,首先來一張uml 圖來表示他們之間的關係。

  • 一個插件對應多個選擇器,一個選擇器對應多個規則。

  • 一個選擇器對應多個匹配條件,一個規則對應多個匹配條件。

  • 每個規則在對應插件下,不同的處理表現為handle欄位,這個一個不同處理的json字串。具體的可以在admin使用過程中進行查看。

接下來我們來熟悉下 soul-admin

話多說幾句:因為篇幅問題,我這裡只是舉一個列子。

  • 我們在divide插件的選擇器配置以上規則,註意 條件:module=test

  • 我們的http配置就是真實服務的路徑:http://10.10.10.4:8088 可以配置多個,然後設置負載方式與權重

我們再來看一下,這個選擇器下麵的規則配置:

  • 同樣我們註意下匹配條件 essay-header 匹配 method = test/putPathBody

如果你是一直看下來的話:我相信你就有了印象,如果我們在http essay-header :

  1. module欄位值設置了 test,
  2. method 欄位值設置了 test/putPathBody

然後訪問soul,那麼soul就會匹配到你的設置最終呼叫http服務為 : http://10.10.10.4:8088/test/putPathBody

發起代理呼叫,最終傳回資料給你,這樣你就完成了一個網關的呼叫 。我們來回想一下,我們做了什麼?

我們訪問網關是 `localhost:8080` 然後設置了http essay-header ,最後真實呼叫為:http://10.10.10.4:8088/test/putPathBody

soul 支持websocket

  • 首先我們來看ws訪問soul網關路徑 ws://localhost:8080/? module=ws&method;=/bbex/websocket/buyAndSell&rpcType;=websocket

    引數詳解:
    1.localhost:8080 是soul啟動的ip和端口。
    2.module(必填):值是你用來匹配selector的關鍵
    3.method (引數): 你的 websocket路徑,同時也用做匹配rule
    4.rpcTypewebsocket 必填,且必須為websocket
  • 這裡websocket 就不能通過essay-header傳了,就要用引數方式了。

dubbo 用戶使用soul

這裡少說兩句了

  • 如果是dubbo集成,那麼rpcType的值為dubbo
  • dubbo引數設置在http body裡面,具體的請查看 dubbo插件

soul 擴展

  • 方式一:如果你只想使用soul插件的責任鏈樣式,那麼只需要實現 org.dromara.soul.web.plugin.SoulPlugin

  • 方式二:如果你想自定義插件,使用soul的選擇器,規則設置,那麼需要繼承org.dromara.soul.web.plugin.AbstractSoulPlugin

  • 篇幅原因請參考:soul擴展

soul自定義開發

  • 其實我更推薦你們自己新建專案來集成soul服務,admin後臺就不需要了。

  • 首先引入soul依賴

  <dependency>
         <groupId>org.dromaragroupId>


         <artifactId>soul-spring-boot-starterartifactId>
         <version>1.0.5-RELEASEversion>
  dependency>

or

  <dependency>
          <groupId>org.dromaragroupId>


          <artifactId>soul-webartifactId>
          <version>1.0.5-RELEASEversion>
   dependency>

  • 在你的新建專案組引入spring-webflux所需要的依賴包。
  • 具體可以參考 以下專案:soul-bootstrap soul-demo

soul未來展望

  • 我覺得soul 做為純java來開髮網關,其低成本,易用性,隨著微服務的流行,肯定會有各種各樣的新需求,希望廣大技術朋友參與進來,提供優秀的代碼與建議。

  • 有人說java語言做網關不如lua,Python等,這個是匪夷所思的。

  • 現在soul是依賴了webflux,個人覺得,後續或者直接使用netty,性能或許會更高。

  • 現在soul依賴於zookeeper,來做配置資料之間的同步,可能會有些重,未來可能會採用http長輪詢的方案來同步更新
    具體的討論在:issues

Soul的具體使用文件:

  • 官網文件 :https://dromara.org/website/zh-cn/docs/soul/index.html
  • github地址: https://github.com/Dromara/soul
  • gitee 地址:https://gitee.com/shuaiqiyu/soul

已同步到看一看
赞(0)

分享創造快樂