全域篩檢程式

GlobalFilter 介面與 GatewayFilter 具有相同的簽章。這些是特殊篩檢程式,有條件地應用於所有路由。

此介面及其使用方式在未來的里程碑版本中可能會有所變更。

組合全域篩檢程式和 GatewayFilter 排序

當請求符合路由時,篩檢程式網路處理常式會將所有 GlobalFilter 實例和所有路由特定的 GatewayFilter 實例新增至篩檢程式鏈。此組合篩檢程式鏈會依 org.springframework.core.Ordered 介面排序,您可以透過實作 getOrder() 方法來設定。

由於 Spring Cloud Gateway 區分篩檢程式邏輯執行的「前置」和「後置」階段(請參閱 運作方式),因此具有最高優先權的篩檢程式在「前置」階段中是第一個,在「後置」階段中是最後一個。

以下清單設定了篩檢程式鏈

ExampleConfiguration.java
@Bean
public GlobalFilter customFilter() {
    return new CustomGlobalFilter();
}

public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("custom global filter");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

閘道指標篩檢程式

若要啟用閘道指標,請新增 spring-boot-starter-actuator 作為專案依賴項。然後,預設情況下,只要未將 spring.cloud.gateway.metrics.enabled 屬性設定為 false,閘道指標篩檢程式就會執行。此篩檢程式會新增一個名為 spring.cloud.gateway.requests 的計時器指標,並帶有以下標籤

  • routeId:路由 ID。

  • routeUri:API 路由到的 URI。

  • outcome:結果,依 HttpStatus.Series 分類。

  • status:傳回給用戶端的請求的 HTTP 狀態。

  • httpStatusCode:傳回給用戶端的請求的 HTTP 狀態碼。

  • httpMethod:用於請求的 HTTP 方法。

此外,透過 spring.cloud.gateway.metrics.tags.path.enabled 屬性(預設為 false),您可以啟用帶有路徑標籤的額外指標

  • path:請求的路徑。

然後,可以從 /actuator/metrics/spring.cloud.gateway.requests 抓取這些指標,並且可以輕鬆與 Prometheus 整合以建立 Grafana 儀表板

若要啟用 prometheus 端點,請新增 micrometer-registry-prometheus 作為專案依賴項。

本機回應快取篩檢程式

如果關聯的屬性已啟用,LocalResponseCache 會執行

  • spring.cloud.gateway.global-filter.local-response-cache.enabled:為所有路由啟用全域快取

  • spring.cloud.gateway.filter.local-response-cache.enabled:啟用關聯的篩檢程式以在路由層級使用

此功能為所有符合以下條件的回應啟用使用 Caffeine 的本機快取

  • 請求是不含內文的 GET。

  • 回應具有以下狀態碼之一:HTTP 200 (OK)、HTTP 206 (Partial Content) 或 HTTP 301 (Moved Permanently)。

  • HTTP Cache-Control 標頭允許快取(表示它沒有以下任何值:請求中存在 no-store,回應中存在 no-storeprivate)。

它接受兩個組態參數

  • spring.cloud.gateway.filter.local-response-cache.size:設定快取的最大大小,以逐出此路由的項目(以 KB、MB 和 GB 為單位)。

  • spring.cloud.gateway.filter.local-response-cache.time-to-live 設定快取項目過期的時間(以 s 表示秒,m 表示分鐘,h 表示小時)。

如果未設定這些參數,但已啟用全域篩檢程式,則預設情況下,它會為快取的回應設定 5 分鐘的存留時間。

此篩檢程式也實作了 HTTP Cache-Control 標頭中 max-age 值的自動計算。如果原始回應中存在 max-age,則該值會以 timeToLive 組態參數中設定的秒數重寫。在後續呼叫中,此值會以回應到期前的剩餘秒數重新計算。

spring.cloud.gateway.global-filter.local-response-cache.enabled 設定為 false 會停用所有路由的本機回應快取,LocalResponseCache 篩檢程式 允許在路由層級使用此功能。

若要啟用此功能,請新增 com.github.ben-manes.caffeine:caffeinespring-boot-starter-cache 作為專案依賴項。
如果您的專案建立自訂 CacheManager bean,則需要標記為 @Primary 或使用 @Qualifier 注入。

轉發路由篩檢程式

ForwardRoutingFilter 在交換屬性 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 中尋找 URI。如果 URL 具有 forward 方案(例如 forward:///localendpoint),它會使用 Spring DispatcherHandler 來處理請求。請求 URL 的路徑部分會被轉發 URL 中的路徑覆寫。未修改的原始 URL 會附加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 屬性中的清單。

Netty 路由篩檢程式

如果位於 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交換屬性中的 URL 具有 httphttps 方案,則 Netty 路由篩檢程式會執行。它使用 Netty HttpClient 來發出下游代理請求。回應會放入 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交換屬性中,以供稍後的篩檢程式使用。(還有一個實驗性的 WebClientHttpRoutingFilter 執行相同的功能,但不需 Netty。)

Netty 寫入回應篩檢程式

如果 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交換屬性中有 Netty HttpClientResponse,則 NettyWriteResponseFilter 會執行。它會在所有其他篩檢程式完成後執行,並將代理回應寫回閘道用戶端回應。(還有一個實驗性的 WebClientWriteResponseFilter 執行相同的功能,但不需 Netty。)

ReactiveLoadBalancerClientFilter

ReactiveLoadBalancerClientFilter 在名為 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的交換屬性中尋找 URI。如果 URL 具有 lb 方案(例如 lb://myservice),它會使用 Spring Cloud ReactorLoadBalancer 將名稱(在本例中為 myservice)解析為實際的主機和埠,並替換相同屬性中的 URI。未修改的原始 URL 會附加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 屬性中的清單。篩檢程式也會在 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 屬性中尋找是否等於 lb。如果是,則適用相同的規則。以下清單設定了 ReactiveLoadBalancerClientFilter

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: myRoute
        uri: lb://service
        predicates:
        - Path=/service/**
預設情況下,當 ReactorLoadBalancer 找不到服務實例時,會傳回 503。您可以設定閘道傳回 404,方法是設定 spring.cloud.gateway.loadbalancer.use404=true
ReactiveLoadBalancerClientFilter 傳回的 ServiceInstanceisSecure 值會覆寫傳送至閘道的請求中指定的方案。例如,如果請求透過 HTTPS 進入閘道,但 ServiceInstance 指出它不安全,則下游請求會透過 HTTP 發出。相反的情況也可能適用。但是,如果在閘道組態中為路由指定了 GATEWAY_SCHEME_PREFIX_ATTR,則會剝離前綴,並且路由 URL 的結果方案會覆寫 ServiceInstance 組態。
閘道支援所有 LoadBalancer 功能。您可以在 Spring Cloud Commons 文件中閱讀更多相關資訊。

RouteToRequestUrl 篩檢程式

如果 ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR 交換屬性中有 Route 物件,則 RouteToRequestUrlFilter 會執行。它會建立一個新的 URI,根據請求 URI,但使用 Route 物件的 URI 屬性更新。新的 URI 會放置在 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交換屬性中。

如果 URI 具有方案前綴,例如 lb:ws://serviceid,則 lb 方案會從 URI 中剝離,並放置在 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 中,以供篩檢程式鏈稍後使用。

Websocket 路由篩檢程式

如果位於 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交換屬性中的 URL 具有 wswss 方案,則 websocket 路由篩檢程式會執行。它使用 Spring WebSocket 基礎架構將 websocket 請求轉發到下游。

您可以透過在 URI 前面加上 lb 來負載平衡 websocket,例如 lb:ws://serviceid

如果您使用 SockJS 作為正常 HTTP 的後備方案,您應該設定正常的 HTTP 路由以及 websocket 路由。

以下清單設定了 websocket 路由篩檢程式

application.yml
spring:
  cloud:
    gateway:
      routes:
      # SockJS route
      - id: websocket_sockjs_route
        uri: http://localhost:3001
        predicates:
        - Path=/websocket/info/**
      # Normal Websocket route
      - id: websocket_route
        uri: ws://localhost:3001
        predicates:
        - Path=/websocket/**

將交換標記為已路由

在閘道路由 ServerWebExchange 之後,它會透過將 gatewayAlreadyRouted 新增至交換屬性,將該交換標記為「已路由」。一旦請求被標記為已路由,其他路由篩檢程式將不會再次路由請求,實際上是跳過篩檢程式。您可以使用便利方法將交換標記為已路由或檢查交換是否已路由。

  • ServerWebExchangeUtils.isAlreadyRouted 採用 ServerWebExchange 物件,並檢查它是否已「路由」。

  • ServerWebExchangeUtils.setAlreadyRouted 採用 ServerWebExchange 物件,並將其標記為「已路由」。