SpringCloud系列之Zuul網關和Zuul過濾器

Zuul網關

什麼是Zuul網關?
Zuul是SpringCloud全家桶的微服務網關。所有從app或者網站(第三方)來的請求都會經過Zuul到達後端的Netflix應用程序。作爲一個邊界性質的應用程序,Zuul提供了動態路由、監控、彈性負載和安全功能。

Zuul底層利用filter實現如下功能:

  1. 認證和安全,識別每個需要認證的資源,拒絕不服務要求的請求。
  2. 性能檢測,在服務邊界追蹤並統計數據,提供精確是生產視圖。
  3. 動態路由,根據需要將請求動態路由到後端集羣。
  4. 壓力測試,逐漸增加對集羣的流量以及瞭解其性能。
  5. 負載卸載,預先爲每種類型的請求分配容量,當請求超過流量時自動丟棄。靜態資源處理,直接再邊界返回某種響應。
  6. 靜態資源處理,直接在Zuul處理靜態資源並響應,而並非轉發這些請求到內部集羣中。
  7. 多區域彈性,跨越AWS區域進行請求路由,旨在實現ELB使用多樣化並保證邊緣位置與使用者儘可能接近。

Zuul網關簡單demo
引入jar包

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

application.yml

server:
  port: 7004  # 端口

spring:
  application:
    name: zuul-getway  # 服務名

eureka:
  client:
    service-url:
      defaultZone: http://jack:666@localhost:8764/eureka/  # 需要註冊到eureka
  instance:
    instance-id: ${spring.application.name}:${server.port}

zuul:
  routes:
    order-service: /od/**  # 對某個服務自定義路由規則
    serviceId: order-service # 這個配置可以實現負載均衡,默認是輪詢
  # 設置某些服務不要進行反向代理 進行路由,多個服務用逗號隔開
  ignored-services: order-service, user-service
  prefix: /api # 請求路徑的前綴

查看是否註冊到eureka
在這裏插入圖片描述
訪問路徑:localhost:7004/api/od/getOrder?token=1235
(後面帶token是因爲我配置了pre過濾器)
在這裏插入圖片描述

Zuul過濾器

Zuul四種過濾器類型,這些類型對應請求的生命週期

  1. pre(前置):在請求被路由之前調用。可利用這種過濾器來實現身份認證、在集羣中選擇請求的微服務,記錄調試等。
  2. routing(路由):將請求路由到微服務。用於構建發送給微服務的請求,並使用apache httpclient或netflix ribbon請求微服務。
  3. post(後置):在路由到微服務後執行。可用於響應添加標準的http header、收集統計信息和指標、將響應從微服務發送到客戶端。
  4. error(錯誤):在其他階段發送錯誤時執行該過濾器。

除了默認的過濾器類型以外Zuul還允許創建自定義的過濾器類型。

如何禁用過濾器?
很簡單,只需設置zuul.ClassName.filterType.disable=true ,即可禁用SimpleClassName所對應的過濾器。
例如:zuul.TokenFilter.pre.disable=true; 即可禁用TokenFilter過濾器

pre過濾器
例子: 鑑權認證。如果參數帶了token就允許訪問

package com.hj.zuulGetway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * pre過濾器
 * @Author Jack.Hu
 */
@Component
public class TokenFilter extends ZuulFilter {

    @Override
    public Object run() {
        System.err.println("執行pre前置過濾器。。。。。。。。。");
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        StringBuffer requestURL = request.getRequestURL();
        System.out.println("requestURL:" + requestURL);
        // 獲取請求的參數
        String token = request.getParameter("token");
        if (StringUtils.isEmpty(token)) {
            // 如果參數爲空則過濾該請求,不對其進行路由
            currentContext.setSendZuulResponse(false);
            // 設置錯誤碼:401
            currentContext.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
            currentContext.set("SUCCESS", false);
        } else {
            // 不過濾該請求,對其進行路由
            currentContext.setSendZuulResponse(true);
            // 設置成功碼:200
            currentContext.setResponseStatusCode(HttpStatus.SC_OK);
            currentContext.set("SUCCESS", true);
        }
        System.out.println("token:" + token);
        return null;
    }

    /**
     * 當前filter類型:pre、post、route、error
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**
     * 表示當前filter優先級
     */
    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    /**
     * 是否執行該過濾器?
     **/
    @Override
    public boolean shouldFilter() {
        return true;
    }
}

POST過濾器
例子: 在返回的時候設置一個cookie

package com.hj.zuulGetway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

/**
 * Post過濾器
 * @Author Jack.Hu
 */
@Component
public class PostFilter extends ZuulFilter {

    /**
     * POST過濾器:在route和error過濾器之後執行
     */
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1;
    }

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

    @Override
    public Object run() {
        System.err.println("執行Post過濾器。。。。。。。。。");
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletResponse response = currentContext.getResponse();
        Cookie cookie = new Cookie("name", "Jack.Hu");
        cookie.setMaxAge(60 * 60 * 24);
        response.addCookie(cookie);
        return null;
    }
}

訪問路徑:localhost:7004/api/od/getOrder
(沒帶token參數)請求被pre過濾器過濾掉了
在這裏插入圖片描述
帶上token參數請求成功!
在這裏插入圖片描述
再按f12看post過濾器設置的cookie
在這裏插入圖片描述
控制檯
在這裏插入圖片描述

以上文章有什麼不對的地方,望大佬們不吝賜教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章