全域性過濾器
GlobalFilter
介面具有與 GatewayFilter
相同的簽名。這些是特殊過濾器,有條件地應用於所有路由。
此介面及其用法可能會在未來的里程碑版本中更改。 |
全域性過濾器和 GatewayFilter
的組合排序
當請求匹配到某個路由時,過濾 web 處理器會將 GlobalFilter
的所有例項和路由特定的 GatewayFilter
所有例項新增到過濾器鏈中。這個組合的過濾器鏈透過 org.springframework.core.Ordered
介面進行排序,你可以透過實現 getOrder()
方法來設定排序。
Spring Cloud Gateway 在過濾器邏輯執行時區分“前置(pre)”和“後置(post)”階段(詳見工作原理),優先順序最高的過濾器在“前置”階段最先執行,在“後置”階段最後執行。
以下列表配置了一個過濾器鏈
@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-store
或private
值)。
它接受兩個配置引數:
-
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:caffeine 和 spring-boot-starter-cache 新增為專案依賴。 |
如果你的專案建立了自定義的 CacheManager bean,則需要將其標記為 @Primary 或使用 @Qualifier 進行注入。 |
Forward 路由過濾器
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 具有 http
或 https
方案,則 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
:
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
預設情況下,當 ReactorLoadBalancer 找不到服務例項時,會返回 503 。你可以透過設定 spring.cloud.gateway.loadbalancer.use404=true 來配置閘道器返回 404 。 |
從 ReactiveLoadBalancerClientFilter 返回的 ServiceInstance 的 isSecure 值會覆蓋傳送到閘道器的請求中指定的方案(scheme)。例如,如果請求透過 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
,則會從 URI 中剝離 lb
方案,並將其放置在 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
中,供過濾器鏈後續使用。
Websocket 路由過濾器
如果位於 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
交換屬性中的 URL 具有 ws
或 wss
方案,則 websocket 路由過濾器會執行。它使用 Spring WebSocket 基礎設施將 websocket 請求轉發到下游。
你可以透過在 URI 前面新增 lb
來對 websocket 進行負載均衡,例如 lb:ws://serviceid
。
如果你使用 SockJS 作為普通 HTTP 的回退方案,你應該配置正常的 HTTP 路由以及 websocket 路由。 |
以下列表配置了一個 websocket 路由過濾器
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
物件,並將其標記為“已路由”。