Spring Cloud之Gateway(三):全域性過濾器
版本:2.0.2.RELEASE
連結:http://spring.io/projects/spring-cloud-gateway#overview
本章主要目錄如下:
Spring Cloud Gateway全域性過濾器是什麼?
本章主要內容如下:
Spring Cloud Gateway全域性過濾器是什麼?
GlobalFilter 介面與 GatewayFilter 具有相同的簽名。這些是有條件地應用於所有路由的特殊過濾器。(這個介面和用法在未來里程碑中會發生變化)。
-
組合的全域性過濾器和閘道器過濾器排序
當請求進入(並匹配到一個路由)時,Filtering Web Handler 會將 GlobalFilter 的所有例項和 GatewayFilter 的所有路由特定例項新增到過濾器鏈中。這個組合的過濾器鏈由org.springframework.core.Ordered 介面排序,可以通過實現 getOrder()方法或使用@Order 註釋來設定。
由於 Spring Cloud Gateway 對過濾器邏輯執行的“pre”階段和“post”階段進行了區分(參見:如何工作),優先順序最高的過濾器將是“pre”階段的第一個,而“post”階段是最後一個。
ExampleConfiguration.java.
@Bean
@Order(-1)
public GlobalFilter a() {
return (exchange, chain) -> {
log.info("first pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("third post filter");
}));
};
}
@Bean
@Order(0)
public GlobalFilter b() {
return (exchange, chain) -> {
log.info("second pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("second post filter");
}));
};
}
@Bean
@Order(1)
public GlobalFilter c() {
return (exchange, chain) -> {
log.info("third pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("first post filter");
}));
};
}
-
Forward 路由過濾器
Forward路由過濾器在 exchange 屬性
ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 中查詢 URI。如果 URL 是forward 協議(即:forward:///localendpoint),它將使用 Spring DispatcherHandler來處理請求。請求 URL 的路徑部分將被轉發 URL 中的路徑覆蓋。未修改的原始 URL 將附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR屬性的列表中。
-
LoadBalancerClient 過濾器
客戶端負載均衡過濾器在 exchange 屬性
ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 中查詢 URI。如果 url 是 lb協議(即 lb:lb://myservice),它將使用 Spring Cloud LoadBalancerClient 將名稱(前一示例中的 myservice)解析為實際主機和埠,並替換 URI 中的相同屬性。未修改的原始 URL 將附加到
ServerWebEServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 屬性的列表中。過濾器還將檢視
ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 屬性以檢視它是否等於 lb,然後應用相同的規則。
application.yml.
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
-
Netty 路由過濾器
如果位於 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange 屬性中的 URL 使用的是 http 或 https 協議,則執行 Netty 路由過濾器。它使用 Netty HttpClient發出下游代理請求。響應放在 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
exchange 屬性中,以便在以後的過濾器中使用。(有一個實驗性的WebClientHttpRoutingFilter 執行相同的功能,但不需要 netty)
-
Netty 寫響應過濾器
如果 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR exchange 屬性中存在 Netty
HttpClientResponse,則執行 Netty 寫響應過濾器。它在所有其他過濾器完成後執行,並將代理響應寫回閘道器客戶端響應。(有一個實驗性的 WebClientWriteResponseFilter 執行相同的功能,但不需要 netty)
-
RouteToRequestUrl 過濾器
如果 ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR exchange 屬性中存在 Route物件,則執行路由到請求地址過濾器。它根據請求 URI 建立一個新 URI,但使用 Route 物件的 URI 屬性進行更新。新 URI 位於
ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange 屬性中。如果 URI具有協議字首,例如lb:ws://serviceid,則 lb 協議將從 URI 中剝離並放置在
ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 中,以便稍後在過濾器鏈中使用。
-
Websocket 路由過濾器
如果ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange 屬性中的 url 是 ws 或 wss 協議,則執行 Websocket 路由過濾器。它使用 Spring Web Socket底層程式碼,來將 Websocket 請求轉發到下游。可以通過在 URI 前面新增 lb 來對 Websockets 進行負載均衡,例如lb:ws://serviceid。
注意:如果在普通 HTTP 上使用 SoCKJs 作為回退,則應配置正常的 HTTP 路由以及Websocket 路由。
application.yml.
spring:
cloud:
gateway:
routes:
# SockJS route
- id: websocket_sockjs_route
uri: http://localhost:3001
predicates:
- Path=/websocket/info/**
# Normwal Websocket route
- id: websocket_route
uri: ws://localhost:3001
predicates:
- Path=/websocket/**
-
閘道器度量過濾器
要啟用閘道器度量,請將 spring-boot-starter-actuator 新增為專案依賴項。然後,預設情況下,只要屬性 spring.cloud.gateway.metrics.enabled 不設定為 false,閘道器度量過濾器就會執行。此過濾器新增名為“gateway.requests”的計時器度量,其中包含以下屬性:
routeId:路由 ID
routeUri:API 將被路由到的 URI
outcome:由 HttpStatus.Series 分類的結果
status:Http 請求返回給客戶端的狀態
然後可以從/actuator/metrics/gateway.requests 中刪除這些指標,並可以很容易地與Prometheus 整合以建立 Grafana 儀表板。
注意:要啟用 pometheus 端點,請將 micrometer-registry-prometheus 新增為專案依賴項。
-
使交換成為路由
在閘道器路由了 ServerWebExchange 之後,它會通過將 gatewayAlreadyRouted 新增到 exchange 屬性來將該交換標記為“路由”。一旦請求被標記為路由,其他路由過濾器將不會再次路由請求,實質上是跳過該過濾器。您可以使用便捷方法將交換標記為路由,或檢查交換是否已路由。
ServerWebExchangeUtils.isAlreadyRouted 使用ServerWebExchange 物件並檢查它是否已是“路由”
ServerWebExchangeUtils.setAlreadyRouted 使用 ServerWebExchange 物件並將其標記為“路由”
如有疑惑,關注公眾號獲取最新內容,下一章將一起討論閘道器TLS / SSL等有關知識點。