API服務閘道器(Zuul) 上
API服務閘道器(Zuul) 上
微服務場景下,每一個微服務對外暴露了一組細粒度的服務。客戶端的請求可能會涉及到一串的服務呼叫,如果將這些微服務都暴露給客戶端,那麼客戶端需要多次請求不同的微服務才能完成一次業務處理,增加客戶端的程式碼複雜度。另外,對於微服務我們可能還需要服務呼叫進行統一的認證和校驗等等。微服務架構雖然可以將我們的開發單元拆分的更細,降低了開發難度,但是如果不能夠有效的處理上面提到的問題,可能會造成微服務架構實施的失敗。 Zuul參考GOF設計模式中的Facade模式,將細粒度的服務組合起來提供一個粗粒度的服務,所有請求都匯入一個統一的入口,那麼整個服務只需要暴露一個api,對外遮蔽了服務端的實現細節,也減少了客戶端與伺服器的網路呼叫次數。這就是API服務閘道器(API Gateway)服務。我們可以把API服務閘道器理解為介於客戶端和伺服器端的中間層,所有的外部請求都會先經過API服務閘道器。因此,API服務閘道器幾乎成為實施微服務架構時必須選擇的一環。 Spring Cloud Netflix的Zuul元件可以做反向代理的功能,通過路由定址將請求轉發到後端的粗粒度服務上,並做一些通用的邏輯處理。 通過Zuul我們可以完成以下功能:
1. 構建閘道器1.1 構建Zuul-Server編寫pom.xml檔案
這裡我們增加了 編寫啟動類 這裡我們增加了對主應用類增加了 編寫配置檔案application.properties 這裡定義服務名稱為: 1.2 構建User-Service為了後面的則是我們再增加一個微服務: 使用者服務。 編寫pom.xml檔案 同樣繼承自我們之前的parent: 編寫啟動類 啟動類和之前的 編寫服務介面 示例的服務介面非常簡單,就是根據給定的登入名稱查詢一個使用者資訊。如下: 其中 編寫配置檔案application.properties 這裡定義服務名稱為: 程式碼修改,就是這麼多,下面讓我們啟動進行測試。 1.3 啟動測試啟動各服務 請按照下面的順序啟動各伺服器:
Ok, 服務啟動後我們可以在Eureka伺服器看到如下介面: Zuul-proxy-010 這裡我們啟動兩個 測試路由服務 首先,我們在瀏覽器中輸入以下地址: http://localhost:8280/product-service/products,將會顯示以下介面: Zuul-proxy-020 然後,我們在瀏覽器中輸入以下地址: http://localhost:8280/user-service/users/admin,將會顯示以下介面: Zuul-proxy-030 可見, 負載均衡測試 接下來我們測試一下負載均衡是否可以正常工作。前面我們已經啟動了兩個 可見,負載均衡也是正常工作的。 Hystrix容錯與監控測試 之前我們是在 Zuul-proxy-050 這說明,Zuul已經整合了Hystrix。
2. Zuul配置2.1 路由配置詳解或許你會覺得神奇,之前我們什麼也沒有配置,通過http://localhost:8280/product-service/products、http://localhost:8280/user-service/users/admin已經可以正確的訪問到我們的微服務了,這就是Zuul的預設路由對映功能在起作用,那麼接下來具體來看看Zuul是怎麼進行路由配置的。 1) 服務路由預設規則 當我們構建API服務閘道器時引入Eureka時,那麼Zuul會自動為每個服務都建立一個預設路由規則: 訪問路徑的字首為 來訪問Product-Service中所提供的products服務端點的原因。 2) 自定義微服務訪問路徑 配置格式為: zuul.routes.微服務Id = 指定路徑,如: 這樣,我們後面就可以通過 所要配置的路徑可以指定一個正則表示式來匹配路徑,因此, 3) 忽略指定微服務 配置格式為: zuul.ignored-services=微服務Id1,微服務Id2...,多個微服務之間使用逗號分隔。如: 4) 同時指定微服務Id和對應路徑 5) 同時指定微服務Url和對應路徑 如之前所述,通過url配置的路由不會由HystrixCommand來執行,自然,也就得不到Ribbon的負載均衡、降級、斷路器等功能。所以在實施儘量使用serviceId進行配置,也可以採用下面的配置方式。 6) 指定多個服務例項及負載均衡 如果需要配置多個服務例項,則配置如下: 7) forward跳轉到本地url 8) 路由字首 可以通過
9) 路由配置順序 如果想按照配置的順序進行路由規則控制,則需要使用YAML,如果是使用propeties檔案,則會丟失順序。例如: 上例如果是使用properties檔案進行配置,則 10) 自定義轉換 我們也可以一個轉換器,讓 這樣,serviceId為“users-v1”的服務,就會被對映到路由為“/v1/users/”的路徑上。任何正則表示式都可以,但是所有的命名組必須包括servicePattern和routePattern兩部分。如果servicePattern沒有匹配一個serviceId,那就會使用預設的。在上例中,一個serviceId為“users”的服務,將會被對映到路由“/users/”中(不帶版本資訊)。這個特性預設是關閉的,而且只適用於已經發現的服務。 2.2 Zuul的Header設定敏感Header設定 同一個系統中各個服務之間通過Headers來共享資訊是沒啥問題的,但是如果不想Headers中的一些敏感資訊隨著HTTP轉發洩露出去話,需要在路由配置中指定一個忽略Header的清單。 預設情況下,Zuul在請求路由時,會過濾HTTP請求頭資訊中的一些敏感資訊,預設的敏感頭資訊通過 對指定路由的可以用下面進行配置: 設定全域性: 忽略Header設定 如果每一個路由都需要配置一些額外的敏感Header時,那你可以通過 在預設情況下是沒有這個配置的,如果專案中引入了 此時,如果還需要使用下游微服務的Spring Security的Header時,可以增加下面的設定: 2.3 Zuul Http ClientZuul的Http客戶端支援Apache Http、Ribbon的RestClient和OkHttpClient,預設使用Apache HTTP客戶端。可以通過下面的方式啟用相應的客戶端:
3. Zuul容錯與回退我們再來仔細看一下之前Hystrix的監控介面: Zuul-proxy-080 請注意,Zuul的Hystrix監控的粒度是微服務,而不是某個API,也就是所有經過Zuul的請求都會被Hystrix保護起來。假如,我們現在把 Zuul-proxy-060 呃,比較鬱悶是麼!那麼如何為Zuul實現容錯與回退呢? Zuul提供了一個 3.1 實現回退方法程式碼如下: 需要說明的是:
3.2 重啟測試重啟 Zuul-proxy-070 說明,回退方法已經起作用了。如果你的沒有起作用,那麼仔細檢查一下 |