推薦一個微服務網關,支持 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的架構圖,有利於加深它的運行原理

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

  • 首先別被這張圖嚇著,我來詳細的講解下,綠色的部分,客戶端就是代表用戶,它按照網關要求的數據格式來請求網關服務。
  • 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 header 頭設置:
  1. module :必填,指請求的系統模塊,建議:所有插件的選擇器中應該根據此字段來匹配
  2. method :必填,請求的方法,指真實請求的方法,如果是http/springcloud,那麼指請求的方法路徑。如果是dubbo,那就是請求的真實方法. 建議:所有插件規則應該根據此字段來匹配過濾請求
  3. rpcType: 請求的類型,填寫http 則會使用divide插件,填寫dubbo則會使用dubbo插件,填寫springcloud則會使用springcloud插件。
  4. 這裡我只有列舉了比較簡單的幾個字段,還有幾個字段未寫,可以在這裡看:請求參數設置

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

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

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

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

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

  • 一個插件對應多個選擇器,一個選擇器對應多個規則。
  • 一個選擇器對應多個匹配條件,一個規則對應多個匹配條件。
  • 每個規則在對應插件下,不同的處理表現為handle字段,這個一個不同處理的json字符串。具體的可以在admin使用過程中進行查看。

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

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

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

  • 我們在divide插件的選擇器配置以上規則,注意 條件:module=test
  • 我們的http配置就是真實服務的路徑:http://10.10.10.4:8088 可以配置多個,然後設置負載方式與權重

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

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

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


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

  1. module字段值設置了 test,
  2. method 字段值設置了 test/putPathBody


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

發起代理調用,最終返回數據給你,這樣你就完成了一個網關的調用 。我們來回想一下,我們做了什麼?

我們訪問網關是 `localhost:8080` 然後設置了http 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.rpcType :websocket 必填,且必須為websocket
  • 這裡websocket 就不能通過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.dromara</groupId>
<artifactId>soul-spring-boot-starter</artifactId>
<version>1.0.5-RELEASE</version>
</dependency>

or

 <dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-web</artifactId>
<version>1.0.5-RELEASE</version>
</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

搜索微信號(ID:芋道源碼),可以獲得各種 Java 源碼解析。

並且,回覆【書籍】後,可以領取筆者推薦的各種 Java 從入門到架構的書籍。

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

來吧,騷年~

相關推薦

推薦中...