天天看點

spring cloud gateway核心概念之斷言和過濾器核心概念1 斷言2 過濾器3 過濾器的順序參考文章

文章目錄

  • 核心概念
  • 1 斷言
    • (1)AfterRoutePredicateFactory
    • (2)BeforeRoutePredicateFactory
    • (3)BetweenRoutePredicateFactory
    • (4)MethodRoutePredicateFactory
    • (5)CookieRoutePredicateFactory
    • (6)HostRoutePredicateFactory
    • (7)HeaderRoutePredicateFactory
    • (8)PathRoutePredicateFactory
    • (9)WeightRoutePredicateFactory
    • (10)RemoteAddrRoutePredicateFactory
    • (11)QueryRoutePredicateFactory
    • (12)CloudFoundryRouteServiceRoutePredicateFactory
    • (13)組合斷言
  • 2 過濾器
    • 2.1 網關過濾器
    • 2.2 全局過濾器
  • 3 過濾器的順序
  • 參考文章

核心概念

  • 路由(Route):路由是網關的基本構件。它由ID、目标URI、一組斷言和一組過濾器組成。如果斷言為真,則比對該路由。gateway使用類RouteDefinition表示路由定義。
  • 斷言(Predicate):參照Java8的新特性Predicate。Predicate接受一個輸入參數,傳回一個布爾值結果,輸入參數可以是HTTP請求的任何部分,比如封包頭、參數、封包體,而且還可以将多個斷言組合在一起。
  • 過濾器(Filter):可以在發送到目标URI之前或之後修改請求和響應。

1 斷言

spring cloud gateway 2.2.9.RELEASE版本裡面,提供了12個斷言,gateway使用工廠模式建立這些斷言,它們都是在斷言工廠裡面建立的。這些斷言工廠都繼承了抽象類AfterRoutePredicateFactory。下面分别介紹這些斷言的作用和例子。

(1)AfterRoutePredicateFactory

該斷言支援設定一個時間,轉發請求時,如果在該時間之後,則斷言為真。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - After=2021-09-10T00:00:00+08:00
           

這個斷言會在東8區的2021-09-10 淩晨12點之後,将請求都轉跳到http://localhost:8079。

(2)BeforeRoutePredicateFactory

與AfterRoutePredicateFactory相反,BeforeRoutePredicateFactory表示在指定的時間之前的請求都進行跳轉。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Before=2021-09-10T00:00:00+08:00
           

這個斷言會在東8區的2021-09-10 淩晨12點之前,将請求都轉跳到http://localhost:8079。

(3)BetweenRoutePredicateFactory

BetweenRoutePredicateFactory接受兩個時間,它表示轉發在指定時間之間的請求。比如:

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Between=2021-09-01T10:00:00+08:00,2021-09-10T12:00:00+08:00 # 比對兩個時間之間
           

(4)MethodRoutePredicateFactory

MethodRoutePredicateFactory根據POST、GET、PUT、DELETE 等不同的HTTP方法進行判斷。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Method=GET
           

上面例子中,所有的GET請求都會被轉發。Method可以指定多個。

(5)CookieRoutePredicateFactory

CookieRoutePredicateFactory根據cookie内容進行判斷。它有兩個參數,一個是cookie名,另一個是value,value使用正規表達式,當cookie中含有指定的cookie名,且值符合value的正規表達式,則将轉發請求。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Cookie=sessionId, test
           

當cookie中含有sessionId=test的内容時,轉發請求。

(6)HostRoutePredicateFactory

HostRoutePredicateFactory使用一組主機清單作為判斷條件。如果目前請求的封包頭中含有屬性“Host”,且其值在指定的主機清單裡面,則将轉發請求。主機清單使用Ant style比對。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Host=**.maven.org,**.spring.org
           

(7)HeaderRoutePredicateFactory

HeaderRoutePredicateFactory指定了兩個參數,一個header的name,一個是正則比對的value。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Header=X-Request-Id, \d+
           

上述規則比對header中存在名為X-Request-Id,内容為數字的請求。

(8)PathRoutePredicateFactory

PathRoutePredicateFactory使用Spring的PathPattern比對請求path。PathPattern支援多種規則,可以使用類似Ant style,也可以使用正規表達式,具體的規則在PathPattern類中有詳細說明。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Path=/demo/** 
           

上述規則比對所有以/demo/開頭的路徑。

(9)WeightRoutePredicateFactory

WeightRoutePredicateFactory基于權重進行路由,配置時指定分組和權重值。下面網頁對于配置規則及算法進行了詳細說明:

https://www.cnblogs.com/liukaifeng/p/10055866.html

(10)RemoteAddrRoutePredicateFactory

RemoteAddrRoutePredicateFactory可以指定被請求的遠端位址,當位址符合要求時,請求才會轉發。可以在位址裡面指定子網路遮罩。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - RemoteAddr=192.168.1.1/24
           

上述例子中,子網路遮罩是24,凡是請求的遠端位址為192.168.1.XXX都會被轉發。

(11)QueryRoutePredicateFactory

QueryRoutePredicateFactory入參也是兩個參數,一個是請求參數的屬性名,另一個是屬性值,屬性值使用正規表達式。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - Query=role,ba.
           

(12)CloudFoundryRouteServiceRoutePredicateFactory

CloudFoundryRouteServiceRoutePredicateFactory在雲計算場景下使用。它判斷header裡面是否有屬性:X-CF-Forwarded-Url、X-CF-Proxy-Signature和X-CF-Proxy-Metadata。當header裡面同時有上述三個屬性時,請求才會被轉發。

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
            - CloudFoundry=XXX
           

CloudFoundry的值對請求轉發不起作用,可以随意寫任何值。

(13)組合斷言

我們可以組合上面介紹的斷言一起使用。比如:

spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: route-demo 
          uri: http://localhost:8079 
          predicates:
          	- Path=/demo/** 
            - Query=role,ba.
            - After=2021-09-10T00:00:00+08:00
           

當所有的斷言都為真時,請求才會被轉發。

2 過濾器

過濾器可以修改HTTP請求的輸入和輸出,Spring Cloud Gateway内置了很多不同功能的過濾器。在gateway中,過濾器有兩個頂級接口,這也将過濾器分為兩類:

  • GatewayFilter:網關過濾器,需要通過

    spring.cloud.routes.filters

    配置在具體路由下,隻作用在目前路由上或通過

    spring.cloud.default-filters

    配置在全局,作用在所有路由上。
  • GlobalFilter:全局過濾器,不需要在配置檔案中配置,作用在所有的路由上,最終通過

    GatewayFilterAdapter

    包裝成

    GatewayFilterChain

    可識别的過濾器。

gateway提供了很多過濾器,本文隻介紹部分過濾器介紹。網關過濾器使用了工廠模式,均是由對應的工廠類建立,工廠類都實作自GatewayFilterFactory接口。

2.1 網關過濾器

(1)AddRequestHeaderGatewayFilterFactory

AddRequestHeaderGatewayFilterFactory可以在header裡面增加指定的name和value。比如:

spring:  
	cloud:    
		gateway:   
        	routes: 
            - id: route-demo
              uri: http://localhost:8079   
              filters:
              - AddRequestHeader=X-Request,BAR
           

對被轉發的請求,會在header裡面額外添加屬性值X-Request=Bar。

(2)AddResponseHeaderGatewayFilterFactory

AddResponseHeaderGatewayFilterFactory在請求響應的header裡面添加指定的name和value。比如:

spring:  
	cloud:   
    	gateway:  
        	routes:      
        	- id: route-demo    
              uri: http://localhost:8079     
              filters:        
              - AddResponseHeader=X-Request,BAR
           

當收到響應後,在header裡面增加屬性值X-Request=Bar。

(3)RemoveRequestHeaderGatewayFilterFactory

RemoveRequestHeaderGatewayFilterFactory在header裡面删除指定的name。

(4)MapRequestHeaderGatewayFilterFactory

MapRequestHeaderGatewayFilterFactory指定兩個header的屬性名:fromHeader和toHeader,轉發請求前,過濾器将屬性名從fromHeader替換為toHeader,屬性值不變。

(5)RewritePathGatewayFilterFactory

RewritePathGatewayFilterFactory可以對請求路徑重寫。過濾器指定兩個參數:regexp和replacement,兩個參數都使用正規表達式,前者指定要替換的内容,後者表示被替換後的内容。

spring:
  cloud:
    gateway:
      routes:
      - id: route-demo
        uri: http://localhost:8079   
        predicates:
        - Path=/foo/**
        filters:
        - RewritePath=/foo/(?<segment>.*), /$\{segment}
           

對于上面的例子,如果請求的路徑是/foo/bar,則gateway會将請求路徑改為/bar發送給下遊。

(6)PrefixPathGatewayFilterFactory

該過濾器工廠為比對的URI添加指定字首。

(7)AddRequestParameter

該過濾器将指定參數添加請求中。

還有其他過濾器,本文不再介紹。請參見文章:

https://blog.csdn.net/abu935009066/article/details/112252692

2.2 全局過濾器

全局過濾器實作了Order接口,該接口的作用用于指定過濾器的順序,數字越小,優先級越高。

(1)NettyWriteResponseFilter

使用Netty與請求方建立的連接配接将收到的代理響應寫回請求端。

(2)GatewayMetricsFilter

該過濾器用于監控,提供監控名額。它統計請求成功、失敗的次數,請求耗時時長等。

該過濾器需要依賴spring-boot-starter-actuator。

(3)NoLoadBalancerClientFilter

該過濾器要求目标URI的schema不能是“

lb

”,否則向請求方傳回404。

lb表示從注冊中心擷取目标URL。
           

如果要使該過濾器失效,則需要引入Ribbon。

(4)WebClientWriteResponseFilter

使用WebClient與請求方建立的連接配接将收到的代理響應寫回請求端。

(5)WebClientHttpRoutingFilter

使用WebClient向目标URI發送

http

https

請求。不過在發送前,要先經過gateway中的其他過濾器處理,在所有的過濾器都處理完畢後,再發送請求。

(6)ForwardRoutingFilter

ForwardRoutingFilter會檢視用戶端請求的URI的schema是否是

forward

,比如:forward://localendpoint,如果是,則它會使用Spring的

DispatcherHandler

來處理這個請求。

(7)ForwardPathFilter

ForwardPathFilter會檢視目标URI的scheme是否是

forward

,比如:

forward://localendpoint

,如果是,則它會使用Spring的

DispatcherHandler

來處理這個請求。

(8)RouteToRequestUrlFilter

這個過濾器用于将從request裡擷取的原始URL轉換成Gateway轉發時所使用的URL。

如果 URL 具有 scheme 字首,例如

lb:ws://serviceid

,該 lb scheme将從URL中剝離,并放到Gateway上下文中,友善後面的過濾器使用。

(9)ReactiveLoadBalancerClientFilter

該過濾器依賴

spring-cloud-starter-loadbalancer

如果原始URL或者目标URL的scheme為“

lb

”,比如:

lb://myservice

,那麼ReactiveLoadBalancerClientFilter使用ReactorLoadBalancer查找myservice的服務位址清單,并且使用負載均衡算法選擇合适的位址。

(10)NettyRoutingFilter

使用Netty的

HttpClient

向目标URI發送

http

https

請求。不過在發送前,要先經過gateway中的其他過濾器處理,在所有的過濾器都處理完畢後,再發送請求。

(11)WebsocketRoutingFilter

使用WebSocketService向目标URI發送

ws

wss

請求。

3 過濾器的順序

當請求到來時,gateway添加所有GlobalFilter執行個體和比對的GatewayFilter執行個體到過濾器鍊中,通過對filter bean配置注解

@Order

,過濾器鍊會對這些過濾器執行個體進行排序。

Spring Cloud Gateway将過濾器的邏輯按請求執行點分為”

pre

”和”

post

”的一前一後處理,如果是高優先級的過濾器,則在”

pre

”邏輯中最先執行,在”

post

”邏輯中最後執行。

參考文章

https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html