pursue wind pursue wind
首页
Java
Python
数据库
框架
Linux
中间件
前端
计算机基础
DevOps
项目
面试
书
关于
归档
MacOS🤣 (opens new window)
GitHub (opens new window)
首页
Java
Python
数据库
框架
Linux
中间件
前端
计算机基础
DevOps
项目
面试
书
关于
归档
MacOS🤣 (opens new window)
GitHub (opens new window)
  • mybatis

  • mybatis-plus

  • Spring

  • SpringBoot

  • SpringSecurity

  • SpringCloud

    • 文档

    • Gateway

      • Spring Cloud Gateway-全局过滤器(Global Filters)
        • 1 Combined Global Filter and GatewayFilter Ordering
        • 2 Forward Routing Filter
        • 3 LoadBalancerClient Filter
        • 4 Netty Routing Filter
        • 5 Netty Write Response Filter
        • 6 RouteToRequestUrl Filter
        • 7 Websocket Routing Filter
        • 8 Gateway Metrics Filter
        • 9 Marking An Exchange As Routed
        • 参考文档
      • Spring Cloud Gateway-路由谓词工厂详解(Route Predicate Factories)
      • Spring Cloud Gateway-过滤器工厂详解(GatewayFilter Factories)
      • Spring Cloud Gateway其他配置
      • Spring Cloud Gateway排错、调试技巧总结
      • Spring Cloud Gateway监控
      • Spring Cloud Gateway限流
    • Spring Cloud Stream

    • Alibaba Sentinel 规则参数总结
    • Alibaba Sentinel规则持久化-拉模式-手把手教程【基于文件】
    • Feign常见问题总结
    • SentinelResource注解 属性总结
    • Spring Cloud Alibaba Sentienl相关配置项
    • SpringCloudAlibaba
    • SpringCloud入门
    • 使用Spring Cloud Feign上传文件
    • 如何使用Feign构造多参数的请求
    • 实用技巧:Hystrix传播ThreadLocal对象(两种方案)
    • 扩展Ribbon支持Nacos权重的三种方式
    • 扩展Ribbon支持基于元数据的版本管理
    • 搭建生产可用的Nacos集群
  • 单元测试框架Mockito
  • 框架
  • SpringCloud
  • Gateway
pursuewind
2020-11-23
目录

Spring Cloud Gateway-全局过滤器(Global Filters)

# Spring Cloud Gateway-全局过滤器(Global Filters)

TIPS

本文基于Spring Cloud Gateway SR2,理论适配Spring Cloud Gateway SR1以及更高版本。

本文详细探讨Spring Cloud Gateway内置的全局过滤器。包括: 1 Combined Global Filter and GatewayFilter Ordering 2 Forward Routing Filter 3 LoadBalancerClient Filter 4 Netty Routing Filter 5 Netty Write Response Filter 6 RouteToRequestUrl Filter 7 Websocket Routing Filter 8 Gateway Metrics Filter 9 Marking An Exchange As Routed

GlobalFilter 接口和 GatewayFilter 有一样的接口定义,只不过, GlobalFilter会作用于所有路由。

TIPS

官方声明:GlobalFilter的接口定义以及用法在未来的版本可能会发生变化。

个人判断:GlobalFilter可用于生产;如果有自定义GlobalFilter的需求,理论上也可放心使用——未来即使接口定义以及使用方式发生变化,应该也是平滑过渡的(比如Zuul的Fallback,原先叫ZuulFallbackProvider,后来改叫FallbackProvider,中间就有段时间新旧使用方式都支持,后面才逐步废弃老的使用方式)。

# 1 Combined Global Filter and GatewayFilter Ordering

当请求到来时,Filtering Web Handler 处理器会添加所有 GlobalFilter 实例和匹配的 GatewayFilter 实例到过滤器链中。

过滤器链会使用 org.springframework.core.Ordered 注解所指定的顺序,进行排序。Spring Cloud Gateway区分了过滤器逻辑执行的”pre”和”post”阶段,所以优先级高的过滤器将会在pre阶段最先执行,优先级最低的过滤器则在post阶段最后执行。

TIPS

数值越小越靠前执行,记得这一点就OK了。

示例代码:

@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");
        }));
    };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

执行结果:

first pre filter
second pre filter
third pre filter
first post filter
second post filter
third post filter
1
2
3
4
5
6

# 2 Forward Routing Filter

ForwardRoutingFilter 会查看exchange的属性 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的值(一个URI),如果该值l的scheme是 forward,比如:forward://localendpoint,则它会使用Spirng的DispatcherHandler 处理该请求。请求URL的路径部分,会被forward URL中的路径覆盖。未修改的原始URL,会被追加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 属性中。

TIPS

这段文档太学术了,讲解了LoadBalancerClientFilter 的实现原理,对使用者来说,意义不大;对使用者来说,只要知道这个Filter是用来做本地forward就OK了。

建议:如对原理感兴趣的,建议直接研究源码,源码比官方文档好理解。

# 3 LoadBalancerClient Filter

LoadBalancerClientFilter 会查看exchange的属性 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的值(一个URI),如果该值的scheme是 lb,比如:lb://myservice ,它将会使用Spring Cloud的LoadBalancerClient 来将 myservice 解析成实际的host和port,并替换掉 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的内容。原始地址会追加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 中。该过滤器还会查看 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 属性,如果发现该属性的值是 lb ,也会执行相同逻辑。

示例:

spring:
  cloud:
    gateway:
      routes:
      - id: myRoute
        uri: lb://service
        predicates:
        - Path=/service/**
1
2
3
4
5
6
7
8

默认情况下,如果无法在 LoadBalancer 找到指定服务的实例,那么会返回503(对应如上的例子,找不到service实例,就返回503);可使用 spring.cloud.gateway.loadbalancer.use404=true 让其返回404。

LoadBalancer 返回的 ServiceInstance 的 isSecure 的值,会覆盖请求的scheme。举个例子,如果请求打到Gateway上使用的是 HTTPS ,但 ServiceInstance 的 isSecure 是false,那么下游收到的则是HTTP请求,反之亦然。然而,如果该路由指定了 GATEWAY_SCHEME_PREFIX_ATTR 属性,那么前缀将会被剥离,并且路由URL中的scheme会覆盖 ServiceInstance的配置

TIPS

这段文档太学术了,讲解了LoadBalancerClientFilter 的实现原理,对使用者来说,意义不大;对使用者来说,其实只要知道这个Filter是用来整合Ribbon的就OK了。

建议:如对原理感兴趣的,建议直接研究源码,源码比官方文档好理解。

# 4 Netty Routing Filter

如果 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的值的scheme是 http 或 https ,则运行Netty Routing Filter 。它使用Netty HttpClient 向下游发送代理请求。获得的响应将放在exchange的 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 属性中,以便在后面的filter中使用。(有一个实验性的过滤器: WebClientHttpRoutingFilter 可实现相同功能,但无需Netty)

# 5 Netty Write Response Filter

如果exchange中的 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 属性中有 HttpClientResponse ,则运行 NettyWriteResponseFilter 。该过滤器在所有其他过滤器执行完成后执行,并将代理响应协会网关的客户端侧。(有一个实验性的过滤器: WebClientWriteResponseFilter 可实现相同功能,但无需Netty)

# 6 RouteToRequestUrl Filter

如果exchange中的 ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR 属性中有一个 Route 对象,则运行 RouteToRequestUrlFilter 。它根据请求URI创建一个新URI,但会使用该 Route 对象的URI属性进行更新。新URI放到exchange的 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 属性中。

如果URI具有scheme前缀,例如 lb:ws://serviceid ,该 lb scheme将从URI中剥离,并放到 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 中,方便后面的过滤器使用。

# 7 Websocket Routing Filter

如果exchange中的 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 属性的值的scheme是 ws或者 wss ,则运行Websocket Routing Filter。它底层使用Spring Web Socket将Websocket请求转发到下游。

可为URI添加 lb 前缀实现负载均衡,例如 lb:ws://serviceid 。

如果你使用 SockJS (opens new window) 所谓普通http的后备,则应配置正常的HTTP路由以及Websocket路由。

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/**
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 8 Gateway Metrics Filter

要启用Gateway Metrics,需添加 spring-boot-starter-actuator 依赖。然后,只要spring.cloud.gateway.metrics.enabled 的值不是false,就会运行Gateway Metrics Filter。此过滤器添加名为 gateway.requests 的时序度量(timer metric),其中包含以下标记:

  • routeId:路由ID
  • routeUri:API将路由到的URI
  • outcome:由 HttpStatus.Series (opens new window) 分类
  • status:返回给客户端的Http Status
  • httpStatusCode:返回给客户端的请求的Http Status
  • httpMethod:请求所使用的Http方法

这些指标暴露在 /actuator/metrics/gateway.requests 端点中,并且可以轻松与Prometheus整合,从而创建一个 Grafana (opens new window) dashboard (opens new window) 。

TIPS

Prometheus是一款监控工具,Grafana是一款监控可视化工具;Spring Boot Actuator可与这两款工具进行整合。关于整合,笔者写过手把手的博客,有兴趣可以看一下:

Spring Boot 2.x监控数据可视化(Actuator + Prometheus + Grafana手把手) (opens new window)

# 9 Marking An Exchange As Routed

在网关路由 ServerWebExchange 后,它将通过在exchange添加一个 gatewayAlreadyRouted 属性,从而将exchange标记为 routed 。一旦请求被标记为 routed ,其他路由过滤器将不会再次路由请求,而是直接跳过。您可以使用便捷方法将exchange标记为 routed ,或检查exchange是否是 routed 。

  • ServerWebExchangeUtils.isAlreadyRouted 检查是否已被路由
  • ServerWebExchangeUtils.setAlreadyRouted 设置routed状态

TIPS

简单来说,就是网关通过 gatewayAlreadyRouted 属性表示这个请求已经转发过了,而无需其他过滤器重复路由。从而防止重复的路由操作。

# 参考文档

  • 114. Global Filters (opens new window)
Last Updated: 2023/01/30, 11:01:00
SpringCloud微服务实战(四)-微服务中的服务拆分
Spring Cloud Gateway-路由谓词工厂详解(Route Predicate Factories)

← SpringCloud微服务实战(四)-微服务中的服务拆分 Spring Cloud Gateway-路由谓词工厂详解(Route Predicate Factories)→

Theme by Vdoing | Copyright © 2019-2023 pursue-wind | 粤ICP备2022093130号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
  • 飙升榜
  • 新歌榜
  • 云音乐民谣榜
  • 美国Billboard榜
  • UK排行榜周榜
  • 网络DJ