天天看點

springcloud元件 ------ Zuul網關介紹搭建Zuul網關伺服器路由過濾器Zuul原理弊端

文章目錄

  • 介紹
  • 搭建Zuul網關伺服器
  • 路由
  • 過濾器
    • 自定義zuulFilter
      • 身份認證示例
  • Zuul原理
  • 弊端

介紹

Zuul是Netflix開源的微服務網關,它可以和Eureka、Ribbon、Hystrix等元件配合使用,Zuul元件核心是一系列過濾器,這些過濾器可以完成:

  • 動态路由:動态将請求路由到不同後端叢集
  • 壓力測試:逐漸增加指向叢集的流量,以了解性能
  • 負載配置設定:為每一種負載類型配置設定對應的容量,并棄用超出限定值的請求
  • 靜态相應處理:邊緣位置進行響應,避免轉發到内部叢集
  • 身份認證和安全:識别每個一資源的驗證要求,并拒絕那些不符合的請求。Spring Cloud對Zuul進行了整合和增強

搭建Zuul網關伺服器

  • 建立一個新的maven工程,引入依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
 </dependency>
           
  • 配置yml
server:
  port: 8888 #端口
spring:
  application:
    name: api-zuul-service #服務名稱
           
  • 啟動類
@SpringBootApplication
//開啟Zuul網關功能
@EnableZuulProxy
public class ZuulServerApplication {

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

}
           

路由

路由:根據請求的url将請求配置設定到對應的微服務中進行處理。

  • 基礎路由配置
#路由配置
zuul:
  routes:
    #例子
    product-service: #路由id
      path: /product-service/**  #映射路徑 #localhost:8888/product-service/xxxxx
      url: http://192.168.0.107:9001/ #映射路徑對應的實際位址
           

通路:http://127.0.0.1:8888/product-service/product/getProduct/1

  • 面向服務的路由配置(整合Eureka)

    1.添加Eureka的依賴

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

2.開啟Eureka的用戶端服務發現

//在啟動類上添加注解(比較新的版本可以不加)
@EnableDiscoveryClient
           

3.在Zuul網關服務中配置Eureka的注冊中心相關資訊

添加eureka配置

#eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9000/eureka/,http://localhost:8999/eureka/
  instance:
    prefer-ip-address: true #使用ip位址注冊
    instance-id: ${spring.cloud.client.ip-address}:${server.port} #向注冊中心中注冊ip
           

4.修改路由中的映射配置

#路由配置
zuul:
  routes:
    #例子
    product-service: #路由id
      path: /product-service/**  #映射路徑 #localhost:8888/product-service/xxxxx
      # url: http://192.168.0.107:9001/ #映射路徑對應的實際位址
      serviceId: product-service #配置轉發的微服務的服務名稱
           
  • 簡化路由配置
#路由配置
zuul:
  routes:
    #如果目前的微服務名稱product-service,預設的請求映射路徑 /product-service/**
    # 如果路由id和對應的微服務的serviceId一緻的話
    product-service: /product-service/**
           

其實不配置也可以,比如,現在配置檔案上沒有配置comsumer-service,但是如果直接通路:http://127.0.0.1:8888/consumer-service/demo/get/1,也是完全沒問題的。

過濾器

Zuul中的過濾器跟我們使用的javax.servlet.Filter不一樣,javax.servlet.Filter隻有一種類型,可以通過配置urlPatterns來攔截對應的請求。而Zuul中的過濾器一共就4種類型,而且每一種類型都有對應的使用場景:

  • PRE:這種過濾器在請求被路由之前調用。我們可以利用這種過濾器實作身份驗證、在集權中選擇請求的微服務、記錄調試資訊等。
  • ROUTING:這種過濾器将請求路由到微服務。這種過濾器用于建構發送給微服務的請求,并使用Apache HttpClient或者Netfilx Ribbon請求微服務。
  • POST:這種過濾器在路由到微服務以後執行。這種過濾器可用來為響應添加标準的HTTP Header、收集統計資訊和名額、将響應從微服務發送給用戶端等。
  • ERROR:在其他階段發生錯誤時執行該過濾器。

    調用順序示意圖:

    springcloud元件 ------ Zuul網關介紹搭建Zuul網關伺服器路由過濾器Zuul原理弊端

自定義zuulFilter

1.繼承ZuulFilter ,實作四個方法

2.将LoginFilter 交給spring容器管理

/**
 * 自定義的zuul過濾器
 * 繼承抽象父類
 * */
@Component
public class LoginFilter extends ZuulFilter {

    /**
     * 定義過濾器類型
     * pre
     * routing
     * post
     * error
     * */
    @Override
    public String filterType() {
        return "pre";
    }


    /**
     * 指定過濾器的執行順序
     *      傳回值越小,執行順序越高
     * */
    @Override
    public int filterOrder() {
        return 1;
    }

    /**
     * 目前過濾氣是否生效
     *  true:使用
     *  false:不适用
     * */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 執行過濾器中的業務邏輯
     * */
    @Override
    public Object run() throws ZuulException {
        System.out.println("執行了過濾器");
        return null;
    }
}

           

身份認證示例

重寫run方法

/**
 * 執行過濾器中的業務邏輯
 *  身份認證:
 *      1.所有的請求需要攜帶一個參數:access-token
 *      2.擷取request請求
 *      3.通過request擷取參數access-token
 *      4.判斷token是否為空
 *      4.1 token == null:身份驗證失敗
 *      4.2 token != null:執行後續操作
 * */
@Override
public Object run() throws ZuulException {
    //1.擷取zuul提供的上下文對象RequestContext
    RequestContext ctx = RequestContext.getCurrentContext();
    //2.從RequestContext中擷取request
    HttpServletRequest request = ctx.getRequest();
    //3.擷取請求參數access-token
    String token = request.getParameter("access-token");
    //4.判斷
    if(token == null){
        ctx.setSendZuulResponse(false);//攔截請求
        ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
    }
    //繼續執行
    return null;
}
           

Zuul原理

springcloud元件 ------ Zuul網關介紹搭建Zuul網關伺服器路由過濾器Zuul原理弊端

弊端

1.請求線程池同步阻塞問題

2.不支援WebSoucket