1. 程式人生 > >SpringCloud實戰9

SpringCloud實戰9

微服務閘道器

   微服務閘道器是介於客戶端與伺服器端的中間層,所有外部請求先經過閘道器。

   微服務閘道器封裝了應用程式的內部結構,客戶端只用跟閘道器互動,而無需直接呼叫特定的微服務介面

Zuul簡介

   Zuul可以通過載入動態過濾機制,從而實現以下各項功能:

  1.驗證與安全保障: 識別面向各類資源的驗證要求並拒絕那些與要求不符的請求。

  2.審查與監控: 在邊緣位置追蹤有意義資料及統計結果,從而為我們帶來準確的生產狀態結論。

  3.動態路由: 以動態方式根據需要將請求路由至不同後端叢集處。

  4.壓力測試: 逐漸增加指向叢集的負載流量,從而計算效能水平。

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

  6.靜態響應處理: 在邊緣位置直接建立部分響應,從而避免其流入內部叢集。

  7.多區域彈性: 跨越AWS區域進行請求路由,旨在實現ELB使用多樣化並保證邊緣位置與使用者儘可能接近。

編寫Zuul微服務閘道器 

   建立一個子專案

   新增pom.xml依賴

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

   啟動類添加註解@EnableZuulProxy   

@SpringBootApplication
@EnableZuulProxy //宣告一個Zuul代理
public class YmkGetewayZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(YmkGetewayZuulApplication.class, args);
    }
}

   修改application,yml

server:
  port: 8040
spring:
  application:
    name: gateway-zuul
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
management:
  security:
    enabled: false

   一個簡單的微服務閘道器就完成了,有配置可知道,添加了Zuul的依賴,並註冊到Eureka Server上。

預設情況下,Zuul會代理所有註冊到Eureka Server上的微服務,並且Zuul的路由規則如下:http://zuul_host:zuul_port/微服務的serviceId/**

   路由配置下詳解

   前文已經編寫了一個簡單的Zuul閘道器,並讓閘道器代理了所有註冊到Eureka Server的微服務,但是現實中可能只想Zuul代理部分微服務,又或者需要對URL的路由配置。

  1、自定義指定微服務的訪問路徑   

zuul:
  routes:
    feign-consumer: /test/**

  2、忽略指定微服務

      忽略多個微服務,逗號分隔即可

zuul:
  ignored-services: feign-consumer

3、忽略所有的服務,只路由指定的服務

zuul:
  ignored-services: '*'   # 使用'*'可忽略所有微服務
  routes:
    feign-consumer: /user/**

4、同時指定微服務的serviceId和對應路徑

zuul:
  routes:
    user-route:                   # 該配置方式中,user-route只是給路由一個名稱,可以任意起名。
      service-id: feign-consumer
      path: /user/**              # service-id對應的路徑

    跟例項1一樣的效果 

5、同時指定path和url

zuul:
  routes:
    user-route:                   # 該配置方式中,user-route只是給路由一個名稱,可以任意起名。
      url: http://localhost:8000/ # 指定的url
      path: /user/**              # url對應的路徑。

這樣就可以將/user/** 對映到http://localhost:8000/**。這種方式配置的路由不會作為HystrixCommand執行,同時也不能用Ribbon來負載均衡多個URL。例項6可解決該問題。

6、同時指定path和url,並且不破壞Zuul的Hystrix,Bibbon特性。

zuul:
  routes:
    user-route:
      path: /user/**
      service-id: feign-consumer
ribbon:
  eureka:
    enabled: false    # 禁用掉ribbon的eureka使用。
feign-consumer:
  ribbon:
    listOfServers: localhost:8000,localhost:8001

7、路由字首

zuul:
  prefix: /api
  routes:
    feign-consumer: /test/**

8、忽略某些路徑

zuul:
  ignoredPatterns: /**/admin/**   # 忽略所有包括/admin/的路徑
  routes:
    feign-consumer: /user/**

 9、本地轉發

zuul:
  routes:
    route-name:
      path: /path-a/**
      url: forward:/path-b

   這樣訪問,Zuul的path/a/**路徑,將轉發到path/b/**

Zuul過濾器

   過濾器是zuul的核心元件,過濾器可以說是Zuul實現API閘道器功能最為核心的部件,每一個進入Zuul的HTTP請求都會經過一系列的過濾器處理鏈得到請求響應並返回給客戶端

   zuul定義了4中標準過濾器


      pre:可以在請求被路由之前呼叫。
      routing:在路由請求時候被呼叫。
      post:在routing和error過濾器之後被呼叫。
      error:處理請求時發生錯誤時被呼叫。
 

編寫一個過濾器  

   新建過濾器類

public class PermisFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String login = request.getParameter("login");
        if (login == null) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.addZuulResponseHeader("content-type","text/html;charset=utf-8");
            ctx.setResponseBody("非法訪問");
        }
        return null;
    }
}

    filterType:該函式需要返回一個字串來代表過濾器的型別,而這個型別就是在HTTP請求過程中定義的各個階段。在Zuul中預設定義了四種不同生命週期的過濾器型別
   filterOrder:通過int值來定義過濾器的執行順序,數值越小優先順序越高。
   shouldFilter:返回一個boolean型別來判斷該過濾器是否要執行。我們可以通過此方法來指定過濾器的有效範圍。
   run:過濾器的具體邏輯。在該函式中,我們可以實現自定義的過濾邏輯,來確定是否要攔截當前的請求,不對其進行後續的路由,或是在請求路由返回結果之後,對處理結果做一些加工等   

    在啟動類,新增過濾器   

@SpringBootApplication
@EnableZuulProxy //宣告一個Zuul代理
public class YmkGetewayZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(YmkGetewayZuulApplication.class, args);
    }

    //配置過濾器Bean
    @Bean
    PermisFilter permisFilter() {
        return new PermisFilter();
    }
}