天天看點

spring cloud 學習(6) - zuul 微服務網關

微服務架構體系中,通常一個業務系統會有很多的微服務,比如:OrderService、ProductService、UserService...,為了讓調用更簡單,一般會在這些服務前端再封裝一層,類似下面這樣:

spring cloud 學習(6) - zuul 微服務網關

前面這一層俗稱為“網關層”,其存在意義在于,将"1對N"問題 轉換成了"1對1”問題,同時在請求到達真正的微服務之前,可以做一些預處理,比如:來源合法性檢測,權限校驗,反爬蟲之類...

傳統方式下,最土的辦法,網關層可以人肉封裝,類似以下示例代碼:

這樣做,當然能跑起來,但是維護量大,以後各個微服務增加了新方法,都需要在網關層手動增加相應的方法封裝,而spring cloud 中的zuul很好的解決了這一問題,示意圖如下:

spring cloud 學習(6) - zuul 微服務網關

Zuul做為網關層,自身也是一個微服務,跟其它服務Service-1,Service-2, ... Service-N一樣,都注冊在eureka server上,可以互相發現,zuul能感覺到哪些服務線上,同時通過配置路由規則(後面會給出示例),可以将請求自動轉發到指定的後端微服務上,對于一些公用的預處理(比如:權限認證,token合法性校驗,灰階驗證時部分流量引導之類),可以放在所謂的過濾器(ZuulFilter)裡處理,這樣後端服務以後新增了服務,zuul層幾乎不用修改。

使用步驟:

一、添加zuul依賴的jar包

二、application.yml裡配置路由

解釋一下:上面這段配置表示,/api-user/開頭的url請求,将轉發到service-provider這個微服務上,/api-order/開頭的url請求,将轉發到service-consumer這個微服務上。

三、熔斷處理

如果網關後面的微服務挂了,zuul還允許定義一個fallback類,用于熔斷處理,參考下面的代碼:

開發人員隻要在getRoute這個方法裡指定要處理的微服務執行個體,然後重寫fallbackResponse即可。

spring cloud 學習(6) - zuul 微服務網關

此時,如果觀察/health端點,也可以看到hystrix處于融斷開啟狀态

spring cloud 學習(6) - zuul 微服務網關

四、ZuulFilter過濾器

過濾器是一個很有用的機制,下面分幾種經典場景示範下:

4.1、token校驗/安全認證

網關直接暴露在公網上時,終端要調用某個服務,通常會把登入後的token傳過來,網關層對token進行有效性驗證,如果token無效(或沒傳token),提示重新登入或直接拒絕。另外,網關後面的微服務,如果設定了spring security中的basic Auth(即:不允許匿名通路,必須提供使用者名、密碼),也可以在Filter中處理。參考下面的代碼:

Filter一共有4種類型,其常量值在org.springframework.cloud.netflix.zuul.filters.support.FilterConstants 中定義

安全校驗,一般放在請求真正處理之前,是以上面的示例filterType指定為pre,剩下的隻要在shouldFilter()、run()方法中重寫自己的邏輯即可。

4.2 動态修改請求參數

zuulFilter可以攔截所有請求參數,并對其進行修改,比如:終端發過來的資料,出于安全要求,可能是經過加密處理的,需要在網關層進行參數解密,再傳遞到後面的服務;再比如:使用者傳過來的token值,需要轉換成userId/userName這些資訊,再傳遞到背後的微服務。參考下面的run方法:

4.3 灰階釋出(Gated Launch/Gray Release) 

大型分布式系統中,灰階釋出是保證線上系統安全生産的重要手段,一般的做法為:從叢集中指定一台(或某幾台)機器,每次做新版本釋出前,先隻釋出這些機器上,先觀察一下是否正常,如果穩定運作後,再釋出到其它機器。這種政策(相當于按部分節點來灰階),大多數情況下可以滿足要求,但是有一些特定場景,可能不太适用。

再比如:後端服務有N多個版本在同時運作,比如V1、V2,現在新加了一個V3版本(這在手機app應用中很常見),希望隻有部分更新了app的使用者通路最新的V3版本服務,其它使用者仍然通路舊版本,待系統穩定後,再大規模提示使用者更新。

對于這些看上去需求各異的灰階需求,