全域性過濾器

GlobalFilter 介面與 GatewayFilter 具有相同的簽名。這些是特殊過濾器,它們有條件地應用於所有路由。

此介面及其用法在未來的里程碑版本中可能會有所更改。

組合全域性過濾器和 GatewayFilter 排序

當請求匹配路由時,過濾 web 處理器會將 GlobalFilter 的所有例項和所有路由特定的 GatewayFilter 例項新增到過濾器鏈中。此組合過濾器鏈透過 org.springframework.core.Ordered 介面進行排序,您可以透過實現 getOrder() 方法來設定它。

由於 Spring Cloud Gateway 區分過濾器邏輯執行的“pre”和“post”階段(請參閱 工作原理),優先順序最高的過濾器在“pre”階段是第一個,在“post”階段是最後一個。

以下列表配置了一個過濾器鏈

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。您可以透過設定 spring.cloud.gateway.loadbalancer.use404=true 來配置閘道器返回 404
ReactiveLoadBalancerClientFilter 返回的 ServiceInstanceisSecure 值會覆蓋請求閘道器時指定的方案。例如,如果請求透過 HTTPS 進入閘道器,但 ServiceInstance 指示不安全,則下游請求將透過 HTTP 進行。相反的情況也可能適用。但是,如果在閘道器配置中為路由指定了 GATEWAY_SCHEME_PREFIX_ATTR,則字首將被剝離,並且路由 URL 中產生的方案將覆蓋 ServiceInstance 配置。
Gateway 支援所有 LoadBalancer 功能。您可以在 Spring Cloud Commons 文件 中閱讀更多相關內容。

RouteToRequestUrl 過濾器

如果 ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR 交換屬性中存在 Route 物件,則 RouteToRequestUrlFilter 會執行。它建立一個新的 URI,該 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: https://:3001
        predicates:
        - Path=/websocket/info/**
      # Normal Websocket route
      - id: websocket_route
        uri: ws://:3001
        predicates:
        - Path=/websocket/**

標記交換已路由

在閘道器路由 ServerWebExchange 之後,它透過向交換屬性新增 gatewayAlreadyRouted 來標記該交換為“已路由”。一旦請求被標記為已路由,其他路由過濾器將不會再次路由該請求,從而跳過該過濾器。您可以使用方便的方法來標記交換已路由或檢查交換是否已路由。

  • ServerWebExchangeUtils.isAlreadyRouted 接受 ServerWebExchange 物件並檢查它是否已被“路由”。

  • ServerWebExchangeUtils.setAlreadyRouted 接受 ServerWebExchange 物件並將其標記為“已路由”。

© . This site is unofficial and not affiliated with VMware.