微服務SpringCloud之GateWay路由

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

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

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

相關概念:

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進行配置。

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

我們先實現一個簡單的路由轉發的demo:

1.引入依賴

這裏需要引入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。

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