1. 程式人生 > >Zuul,閘道器

Zuul,閘道器

路由是微服務架構中必須(integral )的一部分,比如,“/” 可能對映到你的WEB程式上,”/api/users “可能對映到你的使用者服務上,“/api/shop”可能對映到你的商品服務商。(註解:我理解這裡的這幾個對映就是說通過Zuul這個閘道器把服務對映到不同的服務商去處理,從而變成了微服務!)

使用Zuul構建gateway

1. Zuul 簡介

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

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

# 審查與監控:

# 動態路由:動態將請求路由到不同後端叢集

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

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

# 靜態響應處理:邊緣位置進行響應,避免轉發到內部叢集

# 多區域彈性:跨域AWS Region進行請求路由,旨在實現ELB(ElasticLoad Balancing)使用多樣化

Spring Cloud對Zuul進行了整合和增強。目前,Zuul使用的預設是Apache的HTTP Client,也可以使用Rest Client,可以設定ribbon.restclient.enabled=true.

2. 編寫Zuul微服務閘道器

 新增依賴

Zuul的依賴肯定是要加的,如何和Eureka配合使用, Zuul需要註冊到Eureka上,但是Zuul的依賴不包含Eureka Discovery客戶端,所以還需要新增Eureka的客戶端依賴

啟動類加上註解@EnableZuulProxy

它預設加上了@EnableCircuitBreaker和@EnableDiscoveryClient

配置application.yml或者application.properties

***

3. 微服務閘道器相關的配置

 路由路徑的配置

zuul:

 ignoredServices: '*' // 忽略所有請求

  routes:

服務名: /xxx/** //允許將服務名對映到xxx

以下表示只要HTTP請求是 /XXX開始的,就會forward到服務id為users_service的服務上面

zuul:

  routes:

    users: 

      path:/XXX/**  // 路由路徑

     serviceId: users_service // 服務id

zuul:

  routes:

   users:  // 路由名稱,隨意,唯一即可

      path: /XXX/**  // 路由路徑

      url:http://localhost:9000

不破壞Zuul的Hystrix和Ribbon特性

***

使用正則表示式指定Zuul的路由匹配規則

藉助PatternServiceRoute    Mapper實現從微服務到對映路由的正則配置,例如:

 @Bean

      publicPatternServiceRouteMapper serviceRouteMapper(){

           // servicePattern: 指的是微服務的pattern

           // routePattern: 指的是路由的pattern

           // 當你訪問/microservice-provider-user/v1 其實就是

           // localhost:8040/v1/microservice-provider-user/user/1

           return newPatternServiceRouteMapper(

                 "(?<name>^.+)-(?<version>v.+$)","${version}/${name}"

           );

      }

4. Zuul的過濾器

過濾器是Zuul的核心元件,Zuul大部分功能都是通過過濾器來實現的。

4.1. 過濾器型別和請求生命週期

Zuul中定義了四種標準的過濾器型別,這些過濾器型別對應於典型的生命週期。

PRE: 這種過濾器在請求被路由之前呼叫。可利用其實現身份驗證等

ROUTING: 這種過濾器將請求路由到微服務,用於構建傳送給微服務的請求,並使用Apache Http Client或者Netflix Ribbon請求微服務

POST: 這種過濾器在路由到微服務以後執行,比如為響應新增標準的HTTP Header,收集統計資訊和指標,將響應從微服務傳送到客戶端等

ERROR: 在其他階段發生錯誤時執行該過濾器

除了預設的過濾器型別,Zuul還允許建立自定義的過濾器型別。

4.2.  編寫Zuul過濾器

我們只需要繼承抽象類ZuulFilter過濾器即可,讓該過濾器列印請求日誌。

public classPreRequestLogFilter extends ZuulFilter {

 

      private static final Logger logger = LoggerFactory.getLogger(

                 PreRequestLogFilter.class);

      @Override

      public Object run() {

           RequestContext context = RequestContext.getCurrentContext();

           HttpServletRequest reqeust = context.getRequest();

           PreRequestLogFilter.logger.info(

                      String.format("send %srequest to %s",

                      reqeust.getMethod(),

                      reqeust.getRequestURL().toString()));

           return null;

      }

 

      @Override

      public boolean shouldFilter() {

           // 判斷是否需要過濾

           return true;

      }

 

      @Override

      public int filterOrder() {

           // 過濾器的優先順序,越大越靠後執行

           return 1;

      }

 

      @Override

      public StringfilterType() {

           // 過濾器型別

           return "pre";

      }

}

修改啟動類,為啟動類新增:

@SpringBootApplication

@EnableZuulProxy

public classZuulFilterApplication {

      @Bean

      publicPreRequestLogFilter preRequestLogFilter(){

           return newPreRequestLogFilter();

      }

 

      public static void main(String[] args) throws Exception {

           SpringApplication.run(ZuulFilterApplication.class, args);

      }

}

 

5. Zuul聚合微服務

許多場景下,一個外部請求,可能需要查詢Zuul後端多個微服務。比如說一個電影售票系統,在購票訂單頁上,需要查詢電影微服務,還需要查詢使用者微服務獲得當前使用者資訊。如果讓系統直接請求各個微服務,就算Zuul轉發,網路開銷,流量耗費,時長都不是很好的。這時候我們就可以使用Zuul聚合微服務請求,即應用系統只發送一個請求給Zuul,由Zuul請求使用者微服務和電影微服務,並把資料返給應用系統。