Spring Cloud之Gateway(三):全局过滤器

版权声明:本文为博主原创文章,可自由转载、引用,但需注明文章出处。 https://blog.csdn.net/StarskyBoy/article/details/84920512

版本: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

猜你喜欢

转载自blog.csdn.net/StarskyBoy/article/details/84920512