1. 程式人生 > >Spring Cloud(六)服務閘道器zuul

Spring Cloud(六)服務閘道器zuul

為什麼要使用微服務閘道器

不同的微服務閘道器一般都會有不同的網路地址,而外部客戶端(例如手機APP)可能需要呼叫多個服務的接口才能完成一個業務需求。例如一個常見的電商平臺APP,可能會呼叫多個微服務的介面,才能完成一次購物的業務流程,如下圖: 在這裡插入圖片描述 如果讓客戶端直接與各個微服務通訊,會有以下問題:

​ 1 客戶端多次請求不同的微服務,增加了客戶端的複雜性。

​ 2 存在跨域請求,在一定的場景下處理相對複雜。

​ 3 認證複雜,每個微服務都需要獨立認證。

​ 4 難以重構,隨著專案的迭代,可能需要重新劃分微服務。例如,可能將多個微服務合併成一個或者將一個微服務拆分成多個。如果客戶端直接與微服務通訊,那麼重構將會很能實施。

​ 5 某些微服務可能使用了防火牆/瀏覽器不友好的協議,直接訪問會有一定困難。

以上問題可藉助微服務閘道器解決。微服務網路是介於客戶端和服務端之間的中間層,所有的外部請求都會先經過微服務閘道器。使用微服務閘道器後的架構如下: 在這裡插入圖片描述 如上圖,微服務閘道器封裝了應用程式的內部結構,客戶端只須跟閘道器互動,而無須直接呼叫特定微服務的介面。這樣開發就可以得到簡化。不僅如此,使用微服務閘道器還有以下優點:

​ 1 易於監控。可在微服務閘道器收集監控資料並將其推送到外部系統進行分析。

​ 2 易於認證。可在微服務閘道器上進行認證,然後再將請求轉發到後端的微服務,而無須在每個微服務上進行認證。

​ 3 減少了客戶端與各個微服務之間的互動次數。

Zuul簡介

Zuul是Netflix開源的微服務閘道器,它可以和Eureka、Ribbon、hystrix等元件配合使用。Zuul的核心是一系列過濾器。這些過濾器完成以下功能:

​ 1 身份認證和安全:識別每個資源的驗證要求,並拒絕那些與要求不符的請求。

​ 2 審查與監控:在邊緣位置追蹤有意義的資料和統計結果,從而帶來精確的生產檢視。

​ 3 動態路由:動態地將請求路由到不同的後端叢集。

​ 4 壓力測試:逐漸增加指向叢集的流量,以瞭解效能。

​ 5 負責分配:為每一種負載型別分配對應容量,並棄用超出限定值的請求。

​ 6 靜態響應處理:在邊緣位置直接建立部分響應,避免其轉發到內部叢集。

​ 7 多區域彈性:跨越AWS Region進行請求路由,旨在實現ELB(Elastic Load Blancing)使用的多樣化,以及讓系統的邊緣更貼近系統的使用者。

Spring Cloud對Zuul進行了整合與增強。目前,Zuul使用預設HTTP客戶端是Apache HTTP Client,也可使用RestClient或okhttp3.OkHttpClient。如果想要使用RestClient,可以設定ribbon .restclient.enabled=true;想要使用okhttp3.OkHttpClient,可以設定ribbon.okhttp.enabled=true。

構建服務

閘道器服務特別簡單,構建一個新的 SpringBoot 專案,引入閘道器依賴,開啟閘道器即可。

下面我們在 SpringCloud-Learning 專案下建立一個 Model,mz-api-gateway-zuul ,引入對應依賴,POM 如下:

啟動類開啟服務:

建立 bootstrap.xml 的配置檔案,完成閘道器配置:

spring:
  application:
    name: service-cart-zuul

server:
  port: 1004

eureka:
  client:   
  	#間隔多長時間再次獲取登錄檔
    registry-fetch-interval-seconds: 10
    #閘道器是否註冊進註冊中心這裡選擇的否
    register-with-eureka: false  
    #fetch註冊到註冊中心的服務必須是 true
    fetch-registry: true
    serviceUrl:
      defaultZone: http://localhost:1001/eureka/

測試

以此啟動之前的 mz-eureka-server註冊中心、mz-config-serve-git配置中心、mz-eureka-consumer-ribbon消費者,mz-config-consumer-one消費者,以及我們剛剛構建的閘道器服務。

服務路由配置

服務路由我們在上一篇中也已經有過基礎的介紹和體驗,Spring Cloud Zuul通過與Spring Cloud Eureka的整合,實現了對服務例項的自動化維護,所以在使用服務路由配置的時候,我們不需要向傳統路由配置方式那樣為serviceId去指定具體的服務例項地址,只需要通過一組zuul.routes.<route>.pathzuul.routes.<route>.serviceId引數對的方式配置即可。

比如下面的示例,它實現了對符合/ribbon/**規則的請求路徑轉發到名為mz-eureka-consumer-ribon的服務例項上去的路由規則。其中<route>可以指定為任意的路由名稱。例如:

zuul:
  routes:
    route-1:
      path: /client-one/**
      service-id: mz-eureka-client-one
    route-2:
      path: /ribbon/**
      service-id: mz-eureka-consumer-ribon

在Spring Cloud Netflix中,Zuul巧妙的整合了Eureka來實現面向服務的路由。實際上,我們可以直接將API閘道器也看做是Eureka服務治理下的一個普通微服務應用。它除了會將自己註冊到Eureka服務註冊中心上之外,也會從註冊中心獲取所有服務以及它們的例項清單。所以,在Eureka的幫助下,API閘道器服務本身就已經維護了系統中所有serviceId與例項地址的對映關係。當有外部請求到達API閘道器的時候,根據請求的URL路徑找到最佳匹配的path規則,API閘道器就可以知道要將該請求路由到哪個具體的serviceId上去。由於在API閘道器中已經知道serviceId對應服務例項的地址清單,那麼只需要通過Ribbon的負載均衡策略,直接在這些清單中選擇一個具體的例項進行轉發就能完成路由工作了。

專案地址