1. 程式人生 > >第二十五章 Spring cloud Zuul 過濾器

第二十五章 Spring cloud Zuul 過濾器

前言

過濾器是Zuul的核心元件,這篇文章我們來詳細討論Zuul的過濾器。下面話不多說,來看看詳細的介紹吧。

過濾器型別與請求生命週期

Zuul大部分功能都是通過過濾器來實現的。Zuul中定義了四種標準過濾器型別,這些過濾器型別對應於請求的典型生命週期。

(1) PRE:這種過濾器在請求被路由之前呼叫。我們可利用這種過濾器實現身份驗證、在叢集中選擇請求的微服務、記錄除錯資訊等。

(2) ROUTING:這種過濾器將請求路由到微服務。這種過濾器用於構建傳送給微服務的請求,並使用Apache HttpClient或Netfilx Ribbon請求微服務。

(3) POST:這種過濾器在路由到微服務以後執行。這種過濾器可用來為響應新增標準的HTTP Header、收集統計資訊和指標、將響應從微服務傳送給客戶端等。

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

除了預設的過濾器型別,Zuul還允許我們建立自定義的過濾器型別。例如,我們可以定製一種STATIC型別的過濾器,直接在Zuul中生成響應,而不將請求轉發到後端的微服務。

過濾器功能則負責對請求的處理過程進行干預,是實現請求校驗、服務聚合等功能的基礎。然而實際上,路由功能在真正執行時,它的路由對映和請求轉發都是由幾個不同的過濾器完成的。其中,路由對映主要通過pre型別的過濾器完成,它將請求路徑與配置的路由規則進行匹配,以找到需要轉發的目標地址;而請求轉發的部分則是由route型別的過濾器來完成,對pre型別過濾器獲得的路由地址進行轉發。所以,過濾器可以說是Zuul實現API閘道器功能最為核心的部件,每一個進入Zuul的HTTP請求都會經過一系列的過濾器處理鏈得到請求響應並返回給客戶端。

當外部HTTP請求到達API閘道器服務的時候,首先它會進入第一個階段pre,在這裡它會被pre型別的過濾器進行處理,該型別的過濾器主要目的是在進行請求路由之前做一些前置加工,比如請求的校驗等。在完成了pre型別的過濾器處理之後,請求進入第二個階段routing,也就是之前說的路由請求轉發階段,請求將會被routing型別過濾器處理,這裡的具體處理內容就是將外部請求轉發到具體服務例項上去的過程,當服務例項將請求結果都返回之後,routing階段完成,請求進入第三個階段post,此時請求將會被post型別的過濾器進行處理,這些過濾器在處理的時候不僅可以獲取到請求資訊,還能獲取到服務例項的返回資訊,所以在post型別的過濾器中,我們可以對處理結果進行一些加工或轉換等內容。另外,還有一個特殊的階段error,該階段只有在上述三個階段中發生異常的時候才會觸發,但是它的最後流向還是post型別的過濾器,因為它需要通過post過濾器將最終結果返回給請求客戶端

專案結構如下:


EurekaApplication

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;

@EnableZuulProxy
@SpringBootApplication  //開啟啟動程式入口類
public class EurekaApplication {
  public static void main(String[] args) {
    SpringApplication.run(EurekaApplication.class, args);
  }
  /**
   * 即使其它配置都寫好的話,那麼不新增這個 Bean 的方法的話,還是不會執行任何過濾的方法;
   *
   * @return
   */
  @Bean
  public PreFilter preFilter() {
      return new PreFilter();
  }

PreFilter

package com.example.demo;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.LoggerFactory;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

public class PreFilter extends ZuulFilter{

	 private static final org.slf4j.Logger Logger = LoggerFactory.getLogger(PreFilter.class);

	    /**
	     * 前置過濾器。
	     *
	     * 但是在 zuul 中定義了四種不同生命週期的過濾器型別:
	     *
	     *      1、pre:可以在請求被路由之前呼叫;
	     *
	     *      2、route:在路由請求時候被呼叫;
	     *
	     *      3、post:在route和error過濾器之後被呼叫;
	     *
	     *      4、error:處理請求時發生錯誤時被呼叫;
	     *
	     * @return
	     */
	    @Override
	    public String filterType() {
	        return "pre";
	    }

	    /**
	     * 過濾的優先順序,數字越大,優先順序越低。
	     *
	     * @return
	     */
	    @Override
	    public int filterOrder() {
	        return 1;
	    }

	    /**
	     * 是否執行該過濾器。
	     *
	     * true:說明需要過濾;
	     *
	     * false:說明不要過濾;
	     *
	     * @return
	     */
	    @Override
	    public boolean shouldFilter() {
	        return true;
	    }

	    /**
	     * 過濾器的具體邏輯。
	     *
	     * @return
	     */
	    @Override
	    public Object run() {
	        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
	        String host = request.getRemoteHost();
	        Logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
	        Logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
	        Logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
	        Logger.info("                    請求的host:{}                          ", host);
	        Logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
	        Logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
	        Logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
	        return null;
	    }
}

application.yml配置

server:
  port: 8040
spring:
  application:
    name: spring-cloud-zuul-api-gateway-filter
eureka:
  client:
    serviceUrl:
      defaultZone: http://user:[email protected]:8761/eureka
  instance:
    prefer-ip-address: true

zuul: 
  routes:
    users:    #此處可以隨便定義一個,只要唯一就行
      path: /user-path/**     # 一個*號只能匹配一個級別的路徑,比如只能訪問:/user-path/order  而兩個*表示可以匹配多個層級,例如專案訪問路徑為:http://loaclhost:8084/user-path/user/1
      serviceId: spring-cloud-user  #反向代理到這個服務

pom.xml配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example.demo</groupId>
	<artifactId>spring-cloud-zuul-api-gateway-filter</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>spring-cloud-zuul-api-gateway-filter</name>
	<description>spring-cloud-zuul-api-gateway-filter</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.4.1.RELEASE</version>
	</parent>

	<properties>
		<!-- 檔案拷貝時的編碼 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<!-- 編譯時的編碼 -->
		<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
		<!-- jdk版本 -->
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
        <!-- API閘道器模組 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>

        <!-- 客戶端發現模組,由於文件說 Zuul 的依賴裡面不包括 eureka 客戶端發現模組,所以這裡還得單獨新增進來 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>	
		<!-- 用於熱部署 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<!-- 版本依賴管理,故之後新增依賴無需指定version -->
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Camden.SR2</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<!-- 用以為integration-test提供支援。 -->
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

相關推薦

第二 Spring cloud Zuul 過濾器

前言 過濾器是Zuul的核心元件,這篇文章我們來詳細討論Zuul的過濾器。下面話不多說,來看看詳細的介紹吧。 過濾器型別與請求生命週期 Zuul大部分功能都是通過過濾器來實現的。Zuul中定義了四種標準過濾器型別,這些過濾器型別對應於請求的典型生命週期。 (1) PRE:這

第二 Spring cloud Zuul使用正則表示式指定路由規則

Zuul使用正則表示式指定路由規則 EurekaApplication類 package com.example.demo; import org.springframework.boot.SpringApplication; import org.springfra

springcloud系列—Zuul—第5-3: Spring Cloud Zuul過濾器詳解

資料參考:《Spring Cloud 微服務實戰》 目錄 過濾器 請求生命週期 核心過濾器 pre過濾器 route過濾器 post過濾器 過濾器     在Spring Cloud Zuul 中實現的過濾器必須包含4個基本特徵:過濾型別、

第二:Servlet上

作者:java_wxid Servlet技術 a)什麼是Servlet 1、Servlet是一個介面(JavaEE規範) 2、Servlet是執行在伺服器(Tomcat或其他的伺服器)上的小程式。 3、Servlet程式用來接收使用者的請求,和給客戶端響應資料。(接收請求,回傳響應)

Java架構-() 整合spring cloud雲架構 - commonservice-sso服務搭建(一)

前面幾篇我們已經介紹了Spring Cloud和oauth2的知識點,今天我們要利用Spring Cloud和oauth2進行commonservice-sso服務搭建,本節我們只是搭建commonservice-sso的基礎平臺,閒話少說,直接將步驟記錄下來: 建立mave

Spring Cloud 之Eureka服務註冊中心(HA版)

1. Eureka簡介 2. 程式碼實現 2.1涉及的模組 eureka-server-ha:通過profiles指定不同的埠來模擬多服務例項。 eureka-service:服務提供者 2.2

Spring Data JPA

      Java Persistence API是JDK5.0註解或 XML 描述物件——關係表的對映關係,並且將執行期的實體物件持久化到資料庫中 JPA           1. jpa專案搭建:引入相關,依賴jar包           2. 建立持久化實體

C#圖解教程 第二 其他主題

其他主題 概述 在本章中,我會介紹使用C#時的一些重要而又不適合放到其他章節的主題,包括字串操作、可空型別、Main方法、文件註釋以及巢狀型別。 字串 對於內部計算來說0和1很適合,但是對於人類可讀的輸入和輸出,我們需要字串。BCL提供了很多能讓字串操作變得更簡單的類。 C#預定義的

springcloud():Spring Cloud 終於按捺不住推出了自己的服務閘道器 Gateway

Spring 官方最終還是按捺不住推出了自己的閘道器元件:Spring Cloud Gateway ,相比之前我們使用的 Zuul(1.x) 它有哪些優勢呢?Zuul(1.x) 基於 Servlet,使用阻塞 API,它不支援任何長連線,如 WebSockets,Spring Cloud Gateway 使用

程式設計師程式設計藝術-----第二-----二分查詢實現(Jon Bentley:90%程式設計師無法正確實現)

第二十五章:二分查詢實現(Jon Bentley:90%程式設計師無法正確實現)作者:July出處:結構之法演算法之道引言    Jon Bentley:90%以上的程式設計師無法正確無誤的寫出二分查詢程式碼。也許很多人都早已聽說過這句話,但我還是想引用《程式設計珠璣》上的如下幾段文字:  “二分查詢可以解決

程式設計師程式設計藝術第二:Jon Bentley:90%無法正確實現二分查詢

第二十五章:二分查詢實現(Jon Bentley:90%程式設計師無法正確實現) 作者:July 出處:結構之法演算法之道 引言     Jon Bentley:90%以上的程式設計師無法正確無誤的寫出二分查詢程式碼。也許很多人都早已聽說過這句話,但我

Spring cloud 重寫Feign+單個禁用Feign的Hystrix支援

重寫Feign+單個禁用Feign的Hystrix支援 如果Hystrix在類路徑和feign上hystrix。 啟用= true,Feign將用一個斷路器來包裝所有的方法。 返回一個com.netflix.hystrix.HystrixCommand也是可用的。 這允許您

第二:SpringBoot新增支援CORS跨域訪問

CORS(Cross-Origin Resource Sharing)”跨域資源共享”,是一個W3C標準,它允許瀏覽器向跨域伺服器傳送Ajax請求,打破了Ajax只能訪問本站內的資源限制,CORS在很多地方都有被使用,微信支付的JS支付就是通過JS向微信伺服器傳

“全棧2019”Java多線程第二:生產者與消費者線程詳解

工程 java 技術分享 初級 計劃 公眾 圖片 進步 www. 難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文鏈接 “全棧2019”Java多線程第二十五章:生產者與

【WPF學習】第二 日期控制元件

  WPF包含兩個日期控制元件:Calender和DatePicker。這兩個控制元件都被設計為允許使用者選擇日期。   Calendar控制元件顯示日期,在與Windows作業系統中看到的日曆(例如,當配置系統日期時看到的日曆)相似。該控制元件每次顯示一個月份,允許從一個月份跳到另一個月份(通過單擊箭頭按鈕

springcloud系列—Zuul—第5-4: Spring Cloud Zuul 異常處理、禁用過濾器、動態載入

資料參考:《Spring Cloud 微服務實戰》 目錄 異常處理 try-catch處理 ErrorFilter處理 不足與優化 自定義異常資訊 禁用過濾器 動態載入          動態路由  

Spring入門第二

struct java 映射 構造器 into named put per mysq 使用具名參數 直接看代碼: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.

spring cloud: zuul(): prefix訪問字首, ignoredServices粗粒度訪問

 路由的字首 zuul.prefix: 我們可以指定一個全域性的字首 strip-prefix: 是否將這個代理字首去掉 zuul:   prefix: /ecom   strip-prefix: false   routes:   &

SpringBoot | 第二:監控管理之Spring Boot Admin使用

前言 上一章節,我們介紹了Actuator的使用,知道了可通過訪問不同的端點路徑,獲取相應的監控資訊。但使用後也能發現,返回的監控資料都是以JSON串的形式進行返回的,對於實施或者其他人員來說,不是很直觀,而當需要監控的應用越來越多時,依次去訪問對應的應用也過於繁瑣和低效了。所以,本章節來介紹下Spring

python學習手冊(第4版) 第部分:模組 第二 模組:巨集偉藍圖

模組是最高級別的程式組織單元,它將程式程式碼和資料封裝起來以便重用。 每個py檔案是一個模組,匯入模組就可以使用其內部的變數。 模組的優點: 1.程式碼重用 2.物件名稱空間的劃分,物件包含方法/屬性/變數 3.實現共享服務和資料,如使用單例模式/配置檔案