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

本文详细探讨Spring Cloud Gateway内置的全局过滤器。包括:

•Combined Global Filter and GatewayFilter Ordering

•Forward Routing Filter

•LoadBalancerClient Filter

•Netty Routing Filter

•Netty Write Response Filter

•RouteToRequestUrl Filter

•Websocket Routing Filter

•Gateway Metrics Filter

•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");}));};
}

执行结果:

first pre filter
second pre filter
third pre filter
first post filter
second post filter
third post filter

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: myRouteuri: lb://servicepredicates:- Path=/service/**

默认情况下,如果无法在 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[1] 所谓普通http的后备,则应配置正常的HTTP路由以及Websocket路由。

spring:cloud:gateway:routes:# SockJS route- id: websocket_sockjs_routeuri: http://localhost:3001predicates:- Path=/websocket/info/**# Normwal Websocket route- id: websocket_routeuri: ws://localhost:3001predicates:- Path=/websocket/**

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[2] 分类

•status:返回给客户端的Http Status

•httpStatusCode:返回给客户端的请求的Http Status

•httpMethod:请求所使用的Http方法

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

TIPSPrometheus是一款监控工具,Grafana是一款监控可视化工具;Spring Boot Actuator可与这两款工具进行整合。关于整合,笔者写过手把手的博客,有兴趣可以看一下:Spring Boot 2.x监控数据可视化(Actuator + Prometheus + Grafana手把手)[5]

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[6]

References

[1] SockJS: https://github.com/sockjs

[2] HttpStatus.Series: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpStatus.Series.html

[3] Grafana: https://cloud.spring.io/spring-cloud-gateway/reference/html/images/gateway-grafana-dashboard.jpeg

[4] dashboard: https://cloud.spring.io/spring-cloud-gateway/reference/html/gateway-grafana-dashboard.json

[5] Spring Boot 2.x监控数据可视化(Actuator + Prometheus + Grafana手把手): http://www.itmuch.com/spring-boot/actuator-prometheus-grafana/

[6] 114. Global Filters: https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/single/spring-cloud.html#_global_filters


免费分享Java技术资料,需要的朋友私信我

原文:https://mp.weixin.qq.com/s/I7TzWmH7Mcp2Vq_VMDEfzA作者:IT牧场来源:微信公众号

过滤器获取service方法返回慢_Spring Cloud Gateway-全局过滤器(Global Filters)相关推荐

  1. 过滤器获取service方法返回慢_Gateway:自定义过滤器

    自定义局部过滤器 需求:在application.yml中对某个路由配置过滤器,该过滤器可以在控制台输出配置文件中指定名称的请求参数的值. 在gateway-server模块中编写过滤器工厂类MyPa ...

  2. Spring Cloud Gateway(过滤器)

    在上一篇文章中,我们了解了 Spring Cloud Gateway 作为网关所具备的基础功能:路由.本篇我们将关注它的另一个功能:过滤器. Spring Cloud Gateway 已经内置了很多实 ...

  3. gateway中的局部过滤器_Spring Cloud Gateway中的过滤器工厂:重试过滤器

    Spring Cloud Gateway基于Spring Boot 2,是Spring Cloud的全新项目,该项目提供了一个构建在Spring 生态之上的API网关.本文基于的Spring Clou ...

  4. csrf token invalid什么意思_Spring Cloud Gateway 实现Token校验

    在我看来,在某些场景下,网关就像是一个公共方法,把项目中的都要用到的一些功能提出来,抽象成一个服务.比如,我们可以在业务网关上做日志收集.Token校验等等,当然这么理解很狭隘,因为网关的能力远不止如 ...

  5. Spring Cloud Gateway (六) 自定义 Global Filter

    Spring Cloud Gateway (六) 自定义 Global Filter 简介     在前面五篇的分析中,对 Spring Cloud Gateway 的 filter 组件有了一个大概 ...

  6. Spring Cloud GateWay——Filter过滤器

    基于SpringCloud GateWay 3.1.2 版本 内置过滤器 Spring Cloud GateWay 内置了下图中的过滤器,具体的内置过滤器如何使用,可参考官网文档,描述都很简单,本文重 ...

  7. spring gateway 限流持久化_Spring Cloud Gateway网关如何快速实施限流方案?-Part 6

    熔断降级 在分布式系统中,网关作为流量的入口,大量请求进入网关,向后端远程系统或服务发起调用,后端服务不可避免的会产生调用失败(超时或者异常),失败时不能让请求堆积在网关上,需要快速失败并返回回去,这 ...

  8. gatewayfilter详解_Spring Cloud Gateway 之 Filter

    简介 网关经常需要对路由请求进行过滤,进行一些操作,如鉴权之后构造头部之类的,过滤的种类很多,如增加请求头.增加请求 参数 .增加响应头和断路器等等功能,这就用到了Spring Cloud Gatew ...

  9. spring gateway 限流持久化_Spring Cloud Gateway 扩展支持动态限流

    之前分享过 一篇 <Spring Cloud Gateway 原生的接口限流该怎么玩>, 核心是依赖Spring Cloud Gateway 默认提供的限流过滤器来实现 原生Request ...

最新文章

  1. J2EE总结--浅识JNDI
  2. Windows Socket五种I/O模型
  3. 作为初学者,应该如何系统学习Java呢?
  4. python 面向对象编程简称_Python基础-面向对象编程
  5. 【华为云技术分享】ARM体系结构基础(2)
  6. 以太坊扩容项目 Arbitrum 放弃专利,即将上线主网
  7. Hive--sql中的窗口函数
  8. 刘光星- 软件151
  9. 最新原生nodejs调试器的使用大全详解
  10. 【接口测试用例设计思路】
  11. iPad mini2 Vieux降级ios10.3.3 问题解决合集
  12. rufus(u盘引导盘制作工具) v3.5.1497
  13. php去掉省市区,PHP简单实现正则匹配省市区的方法
  14. python终止运行无反应_终止运行Python应用程序(Terminate Running Python Apps)
  15. 一键加速GitHub、Pypi、DockerHub访问
  16. php实训日记200字,做实验日记200字
  17. 侯捷C++视频资源全集 | 百度网盘下载
  18. 戴尔笔记本Windows10安装Ubuntu18.04实现双系统总结
  19. 针对等额本金还款模式的客户,写一个程序按顺序输入贷款总额(单位为万元)、月利率、贷款总月数,输出第一个月客户还款金额(单位为元,取整数)。
  20. 基于 next.js + mdx 搭建组件库文档项目(一) -- 开发环境搭建

热门文章

  1. MySQL每秒57万的写入,快还是慢?
  2. 刑侦高考:如何用SQL解决环环相扣的刑侦推理问题
  3. 未完待续:关于DB Link和SCN,你还需要知道的是...
  4. 鸿蒙轻内核M核源码分析:中断Hwi
  5. Rust布道者张汉东倾授,入门Rust初学者都要攻破哪些难点?
  6. 华为云专家私房课:视频传输技术选型的三大法宝
  7. 微服务架构下,DLI的部署和运维有何奥秘?
  8. 【IoT最佳实践】设备获取实时天气DEMO代码解读
  9. 揪出MySQL磁盘消耗迅猛的真凶
  10. 小白学HarmonyOS,HarmonyOS 2.0正式发布 分布式能力获得全面升级