網關Ocelot功能演示安排的明明白白~~~


前言

網關(Gateway)在微服務架構中至關重要,可以將其理解為是外部客戶端(前端、MVC后台等調用方)與后台服務的連接點,通過這層可以做統一的處理,比如路由、身份認證和授權、服務治理等;

網關的好處:

  • 統一入口,調用方(客戶端)不在為調哪個服務而頭大,統一入口即可,由網關路由到對應后台服務;
  • 統一處理公共邏輯,比如認證和授權,避免相同邏輯多處實現,易於維護;
  • 對后台服務可以做負載均衡,根據指定的負載算法找到合適的后台服務調用,而這些細節調用方都不用理會,只管調就行啦;
  • 初步過濾非法請求,可以根據配置的請求規則過濾掉非法請求;
  • 屏蔽各服務真實地址,間接保證各服務的安全

網關帶來的問題:

  • 在請求過程中,多增加了一層(網關)對請求進行處理,會消耗一些性能;
  • 高並發場景,對網關性能要求高,需要開發人員要有足夠的能力處理;

整體來看,在微服務架構中,網關帶來的便捷和好處肯定大於自身帶來的問題,所以不必糾結於此。

目前常用的網關有Kong、Tyk、Zuul、Ambassador、Ocelot等,而在.Net中比較火的是Ocelot和Kong,接下來就以Ocelot為主展開來聊聊。

正文

Ocelot是一個用.NET Core實現並且開源的API網關,它功能強大,除了路由、請求聚合、負載均衡等功能外,還可以集成Consul做服務發現,集成Polly做服務治理等; 相關功能只需簡單的配置即可實現。接下來就把比較常用的功能依次舉例演示一把,小伙伴們,搞起來~~~

0. 先把項目建好

整個演示中會使用到三個角色:網關層(端口為5000)、后台服務1(端口為8000)、后台服務2(端口為8001)。項目結構如下:

項目結構

網關對應代碼如下:

網關代碼

由於使用的是.NetCore3.1進行演示,則需要的Ocelot包版本最新為16.0.1,然后將對應服務和中間件進行注冊;由於Ocelot是通過配置文件進行功能配置的,所以需要一個配置文件,並指定對應的路徑;這里的ocelot.json(名字自定義就行)就放在根目錄下,將文件屬性改為始終復制或如果較新則復制,配置文件內容在下面會細說;這里網關層就完工啦;

兩個后台服務接口基本上沒動,只是將ServiceAPI1的端口改為8000,ServiceAPI2的端口改為8001;為了后續配置演示,分別新增了控制器,如下圖:

服務接口

1. 路由

路由是指網關根據原始請求,匹配對應的路由配置規則,將其轉發到真正的后台服務接口;這是網關的核心功能。

1.1 配置初體驗

通過配置,實現統一入口(網關),訪問后台兩個不同的服務接口,如下配置:

{
  "Routes": [
    {
      "UpstreamPathTemplate": "/OcelotTest1/{url}",
      "UpstreamHttpMethod": [ "Get"],
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 8000
        }
      ]
    },
    {
      "UpstreamPathTemplate": "/OcelotTest2/{url}",
      "UpstreamHttpMethod": [ "Get"],
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 8001
        }
      ]
    }
  ]
}

配置項解析:

  • Routes:這是個數組,將所有請求處理都配置在里面,每一個請求處理是一個對象;
  • UpstreamPathTemplate:上游請求路徑模板;即對應調用方發出的請求,如不符合這個規則,就會被過濾掉;
  • UpstreamHttpMethod:上游請求的方式,可以傳遞多個,比如["Get","Post"];
  • DownstreamPathTemplate:下游請求的路徑模板;對應真實API的請求地址,只有符合規則,才會正常轉發到服務接口上;
  • DownstreamScheme:指定下游是http還是https;
  • DownstreamHostAndPorts:指定下游的Host和端口,這里可以寫多個,多個時可以配置負載均衡;

將網關、后台服務接口1和后台服務接口2運行啟動,訪問如下:

路由訪問

如路由配置所示,可以用{參數}這種形式,通過上游請求模板傳遞給下游請求模板中;

1.2 設置匹配的優先級

當請求匹配到配置的多個路由規則時,會選擇配置在最前面的路由規則進行轉發,可能不是自己需要,如下:

默認先配置先匹配

遇到這種情況可以調整配置位置來滿足需求,但明顯不合理,Ocelot提供優先級(Priority)的配置,配置的值越大就越優先匹配,默認所有配置的路由優先級的值為0;如下配置可以滿足需求:

路由優先級

在配置文件中可以配置萬能模板,即所有請求都會匹配到該路由模板,但其優先級為最低,如果能匹配到其他模板,優先走其他路由,萬能模板配置如下:

萬能模板

1.3 區分匹配路由大小寫

默認情況下,匹配路由是不區分大小寫的;其實在實際過程中我們通常也不需要區分;但在一些應用場景要求區分大小,那就可以增加"RouteIsCaseSensitive": true配置即可。

2. 路由聚合

路由聚合就是可以將多個一般的路由(上面配置的路由就是)聚合在一起,然后將多個路由響應的結果統一返回給調用方;如下配置

image-20210402123033237

配置說明:

  • 路由配置中增加了Key,給需要聚合的路由分別配置一個不重復的Key值;
  • 在配置文件中增加Aggregates節點,這個節點和Routes節點是同級的;然后在里面的RouteKeys中配置需要聚合的路由Key,然后再配置一個上游模板路徑,配置上游模板路徑時同樣可以傳遞參數,如上圖所示;

運行結果:

image-20210402123819897

其實在剛開始直接返回字符串時(通常都是是返回Json,只是這里演示遇到了不規范情況,剛好可以說說),返回的結果並不是真正的Json字符串,這樣可能前端解析就會出問題,所以需要處理一下返回結果;

如果不處理,就會出現如下情況:

返回結果不對

上圖中在沒處理之前,網關是直接將結果進行拼接,但最后整體不符合Json格式,JsonView就報錯啦!!!

解決措施就是將字符串以Json的形式返回即可,簡單的處理方式如下:

優化之后

上面的聚合演示是默認情況,Ocelot提供自定義聚合器的功能(繼承IDefinedAggregator接口),並注冊相關服務,然后在配置文件指定自定義的聚合器即可,如下(具體細節請詳見官網):

image-20210402124814838

具體實現這里就不再演示了,好像自定義聚合器功能用的不太多,通常大家的做法是單獨做一個后台聚合服務,若需要聚合數據,從聚合服務中獲取即可;

3. 集成Consul做服務發現

如果還是通過配置文件一個一個的配置路由,是不是也太不給力啦,如果能和Consul結合,豈不是完美~~~

3.1 先把Consul集成到網關項目中

引入Ocelot.Provider.Consul,並在ConfigureServices中注冊相關服務組件;

image-20210402134110433

3.2 在配置文件中增加Consul相關配置;

image-20210402223213939

配置文件說明:

  • GlobalConfiguration:全局配置,其實可以理解為所有路由共用的配置放在這;

  • ServiceDiscoveryProvider:服務發現的相關配置,Scheme代表用的是http還是https;Host代表的是Consul啟動的主機;Port代表Consul啟動的Http端口;Type這里使用的是Consul這種服務發現,可以指定其他服務發現框架;

  • BaseUrl:這個配置主要網關對外暴露的地址,也就是調用者使用的地址;

Routes中多了兩個和一般路由不同的配置,如下:

  • ServiceName:指定服務名,這里是Consul注冊服務時指定的服務名,根據這個名字內部可以獲取到對應的Host和端口;所以有了ServiceName,就可以不用手動配置Host和端口啦;

  • LoadBalancerOptions:指定負載均衡算法,其實這里咱們還沒有說到負載均衡,但如果不配置會報錯,所以就提前配置上了;

3.3 啟動Consul服務

將兩個后台服務接口注冊到Consul中;(過程就不細說啦,詳細參考來,Consul 服務發現入個門(一看就會的那種)運維小姐姐說這篇Consul集群和ACL配置超給力(保姆級)這兩篇文章);這里用配置文件的方式,如下配置文件:

image-20210402221640328

然后啟動Consul即可,這里為了演示方便,直接就用開發者模式啦;

3.4 運行結果

image-20210402222950495

3.5 動態路由

除了以上顯示指定服務名之外,其實可以動態路由,如下配置運行:

image-20210402225019606

Routes節點不需要配置任何路由;

4. 負載均衡

在高並發場景,后台服務是需要做集群部署的,而Ocelot可以在配置路由規則時,開啟負載均衡功能,並指定對應的均衡算法,從而實現請求按算法轉發到后台服務。

4.1 模擬集群環境

為了方便演示集群效果,這里將后台服務主機的端口打印出來,代碼如下:

image-20210403002543495

然后通過命令的方式,將ServiceAPI1后台服務啟動多個,只是端口不一樣而已;如下:

image-20210403221010139

4.2 將啟動起來的服務配置網關中

啟動起來之后,將他們配置到路由中,如下:

image-20210403204553359

配置解析:

  • DownstreamHostAndPorts中配置多個啟動的后台服務Host和端口;
  • LoadBalancerOptions指定負載均衡算法,圖中指定的是輪詢,通常有以下幾種:
    • LeastConnection 把新請求轉發到請求最少的后台服務上;
    • RoundRobin 將請求輪詢輪詢轉發都配置的后台服務上;
    • NoLoadBalancer 不負載均衡;
    • CookieStickySessions 使用cookie關聯相關的請求到指定的服務;
4.3 網關運行起來看效果

image-20210403220600727

4.4 搭配Consul一塊用

首先進行修改Consul的配置文件,然后將其啟動,見下圖:

image-20210403221739328

如上圖所示,在相同服務名ServiceAPI1Name下面注冊了兩個服務,一個端口是8000,一個端口是8003;

然后在網關中修改一下配置,然后啟動:

image-20210403222306562

咦,到這發現篇幅略長啦,先暫停吧;另外Polly這個知識點之前沒聊過,下期先補上,然后繼續聊其他功能~~~

總結

本來想通過一篇文章把常用的功能點演示一下的,篇幅太長不太好(小伙伴有反應);下期會繼續說Ocelot集成CacheManager做緩存、集成IdentityServer4做認證授權、集成Polly做服務治理。

一個被程序搞丑的帥小伙,關注"Code綜藝圈",跟我一起學~~~

圖片


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM