1. 程式人生 > >Spring Cloud之Gateway(三):全域性過濾器

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等有關知識點。

本文對應公眾號連結:https://mp.weixin.qq.com/s/b_6Fcs-uWWZ-qNqFs8lGwA