微服務SpringCloud之GateWay路由

在前面博客學習了網關zuul,今天學下spring官方自帶的網關spring cloud gateway。Zuul(1.x) 基於 Servlet,使用阻塞 API,它不支持任何長鏈接,如 WebSockets,Spring Cloud Gateway 使用非阻塞 API,支持 WebSockets,支持限流等新特性。java

Spring Cloud Gateway 是 Spring Cloud 的一個全新項目,該項目是基於 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技術開發的網關,它旨在爲微服務架構提供一種簡單有效的統一的 API 路由管理方式。正則表達式

Spring Cloud Gateway 做爲 Spring Cloud 生態系統中的網關,目標是替代 Netflix Zuul,其不只提供統一的路由方式,而且基於 Filter 鏈的方式提供了網關基本的功能,例如:安全,監控/指標,和限流。spring

相關概念:apache

Route(路由):這是網關的基本構建塊。它由一個 ID,一個目標 URI,一組斷言和一組過濾器定義。若是斷言爲真,則路由匹配。
Predicate(斷言):這是一個 Java 8 的 Predicate。輸入類型是一個 ServerWebExchange。咱們可使用它來匹配來自 HTTP 請求的任何內容,例如 headers 或參數。
Filter(過濾器):這是org.springframework.cloud.gateway.filter.GatewayFilter的實例,咱們可使用它修改請求和響應。
工做流程:瀏覽器

 

客戶端向 Spring Cloud Gateway 發出請求。若是 Gateway Handler Mapping 中找到與請求相匹配的路由,將其發送到 Gateway Web Handler。Handler 再經過指定的過濾器鏈來將請求發送到咱們實際的服務執行業務邏輯,而後返回。 過濾器之間用虛線分開是由於過濾器可能會在發送代理請求以前(「pre」)或以後(「post」)執行業務邏輯。緩存

Spring Cloud Gateway 的特徵:安全

  1. 基於 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
  2. 動態路由
  3. Predicates 和 Filters 做用於特定路由
  4. 集成 Hystrix 斷路器
  5. 集成 Spring Cloud DiscoveryClient
  6. 易於編寫的 Predicates 和 Filters
  7. 限流
  8. 路徑重寫

Spring Cloud Gateway 網關路由有兩種配置方式,這裏建議使用yml進行配置。cookie

  1. 在配置文件 yml 中配置
  2. 經過@Bean自定義 RouteLocator,在啓動主類 Application 中配置

咱們先實現一個簡單的路由轉發的demo:架構

1.引入依賴app

這裏須要引入spring-cloud-starter-gateway。

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>SpringCloudGatewayDemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>SpringCloudGatewayDemo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies> 
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
View Code

2.建立application.yml增長配置

server:
  port: 8081
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://www.cnblogs.com
        predicates:
          - Path=/5ishare

各字段含義以下:

id:咱們自定義的路由 ID,保持惟一
uri:目標服務地址
predicates:路由條件,Predicate 接受一個輸入參數,返回一個布爾值結果。該接口包含多種默認方法來將 Predicate 組合成其餘複雜的邏輯(好比:與,或,非)。
filters:過濾規則,本示例暫時沒用。

上面這段配置的意思是,配置了一個 id 爲 neo_route 的路由規則,當訪問地址 http://localhost:8081/5ishare時會自動轉發到地址:http://www.cnblogs.com/spring-cloud。配置完成啓動項目便可在瀏覽器訪問進行測試,當咱們訪問地址http://localhost:8080/5ishare 時會展現https://www.cnblogs.com/5ishare頁面。

路由規則

Spring Cloud Gateway 的功能很強大,咱們僅僅經過 Predicates 的設計就能夠看出來,前面咱們只是使用了 predicates 進行了簡單的條件匹配,其實 Spring Cloud Gataway 幫咱們內置了不少 Predicates 功能。

Spring Cloud Gateway 是經過 Spring WebFlux 的 HandlerMapping 作爲底層支持來匹配到轉發路由,Spring Cloud Gateway 內置了不少 Predicates 工廠,這些 Predicates 工廠經過不一樣的 HTTP 請求參數來匹配,多個 Predicates 工廠能夠組合使用。

Predicate 介紹
Predicate 來源於 Java 8,是 Java 8 中引入的一個函數,Predicate 接受一個輸入參數,返回一個布爾值結果。該接口包含多種默認方法來將 Predicate 組合成其餘複雜的邏輯(好比:與,或,非)。能夠用於接口請求參數校驗、判斷新老數據是否有變化須要進行更新操做。

在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性實現了各類路由匹配規則,有經過 Header、請求參數等不一樣的條件來進行做爲條件匹配到對應的路由。網上有一張圖總結了 Spring Cloud 內置的幾種 Predicate 的實現。

 

經過時間匹配
Predicate 支持設置一個時間,在請求進行轉發的時候,能夠經過判斷在這個時間以前或者以後進行轉發。這裏使用After來設置該時間以後轉發,Before來設置該時間以前轉發,Between來設置該時間區間端轉發。在測試的過程當中開始設置After轉發以後再修改另外兩個Before和Between時不起做用了,須要清下瀏覽器緩存。

server:
  port: 8081
spring:
  cloud:
    gateway:
      routes:
       - id: time_route
         uri: http://www.cnblogs.com
         predicates:
          -After=2019-11-03T10:20:06+08:00[Asia/Shanghai]
#          - Before=2019-11-03T10:55:06+08:00[Asia/Shanghai]
#          - Between=2019-11-03T11:01:06+08:00[Asia/Shanghai], 2019-11-03T11:05:06+08:00[Asia/Shanghai]

經過 Cookie 匹配

 Cookie Route Predicate 能夠接收兩個參數,一個是 Cookie name ,一個是正則表達式,路由規則會經過獲取對應的 Cookie name 值和正則表達式去匹配,若是匹配上就會執行路由,若是沒有匹配上則不執行。以下圖所示,當在請求的Cookie中添加name=cuiyw時跳轉到http://www.cnblogs.com,當不添加時報404錯誤。

經過 Header 屬性匹配

Header Route Predicate 和 Cookie Route Predicate 同樣,也是接收 2 個參數,一個 header 中屬性名稱和一個正則表達式,這個屬性值和正則表達式匹配則執行。以下圖所示當設置X-Request-Id=6666時頁面跳轉正常,當設置爲cuiyw時報404錯。

server:
  port: 8081
spring:
  cloud:
    gateway:
      routes:
       - id: cookie_route
         uri: http://www.cnblogs.com
         predicates:
           - Cookie=name,cuiyw
           - Header=X-Request-Id, \d+

 

 

 經過 Host 匹配

 Host Route Predicate 接收一組參數,一組匹配的域名列表,這個模板是一個 ant 分隔的模板,用.號做爲分隔符。它經過參數中的主機地址做爲匹配規則。這裏沒測試出來,暫時略過。

經過請求方式匹配

能夠經過是 POST、GET、PUT、DELETE 等不一樣的請求方式來進行路由,以下配置文件配置的是使用Get請求來進行路由,若是使用post則報404錯誤

server:
  port: 8081
spring:
  cloud:
    gateway:
      routes:
       - id: method_route
         uri: http://www.cnblogs.com
         predicates:
          - Method=GET

 

經過請求路徑匹配

 Path Route Predicate 接收一個匹配路徑的參數來判斷是否走路由。當輸入http://localhost:8081/5ishare時報404錯誤,當輸入http://localhost:8081/5ishare/p正常跳轉。

server:
  port: 8081
spring:
  cloud:
    gateway:
      routes:
       - id: method_route
         uri: http://www.cnblogs.com
         predicates:
          - Method=GET
          - Path=/5ishare/{segment}

 

經過請求參數匹配

 Query Route Predicate 支持傳入兩個參數,一個是屬性名一個爲屬性值,屬性值能夠是正則表達式。當輸入http://localhost:8081/5ishare時報404錯誤,當輸入http://localhost:8081/5ishare?name=cuiyw時跳轉正常

 

 經過請求 ip 地址進行匹配

Predicate 也支持經過設置某個 ip 區間號段的請求才會路由,RemoteAddr Route Predicate 接受 cidr 符號(IPv4 或 IPv6 )字符串的列表(最小大小爲1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子網掩碼)。這個目前沒找到驗證方法,暫時略過。

組合使用

在上面的例子有就能看到多個匹配組合在一塊兒使用。例如經過Header屬性匹配中設置了Cookie和Header。

相關文章
相關標籤/搜索