内容简介:本文基于Spring Cloud Gateway 2.1.1.RELEASE。在讲SCG的Filter的排序问题之前得先比较一下Spring Cloud Gateway在对待Filter的方面与Zuul2有着哪些不同。SCG所谓Route Filter就是像下面这样的:
本文基于Spring Cloud Gateway 2.1.1.RELEASE。
在讲SCG的Filter的 排序 问题之前得先比较一下Spring Cloud Gateway在对待Filter的方面与Zuul2有着哪些不同。
Filter的Scope
- SCG采用的是Global Filter和Route Filter相结合的方式
- Zuul2则都是Global Filter
SCG所谓Route Filter就是像下面这样的:
spring: cloud: gateway: routes: - id: tomcat_route uri: http://tomcat:8080 predicates: - Path=/tomcat/docs filters: - StripPrefix=1 - RemoveRequestHeader=X-Request-Foo
上面的 StripPrefix
和 RemoveRequestHeader
就是Route Filter,而SCG的Global Filter则是隐式的,无需显式配置,它们会在请求过来的时候被SCG调用。
也就是说你可以配置不同的Route,然后为每个Route配置不同的Route Filter,这一切都是在配置阶段就决定下来的。
而Zuul2则都是Global Filter,因此你得运行时在每个Filter内部自己决定是否要干活,除此之外,发送到Origin(被代理的服务)的url也得你自己设置,下面是一个例子(来自 Zuul2 Sample ):
public class Routes extends HttpInboundSyncFilter { @Override public boolean shouldFilter(HttpRequestMessage httpRequestMessage) { // ... return true; } @Override public HttpRequestMessage apply(HttpRequestMessage request) { // ... // Route healthchecks to the healthcheck endpoint.; context.setEndpoint(ZuulEndPointRunner.PROXY_ENDPOINT_FILTER_NAME); context.setRouteVIP("tomcat"); return request; } }
Filter的角色
- 在SCG概念中只有一种Filter(撇开Global和Route的区别),它用代码来区分Pre Filter、Post Filter。在文档中还提到了Routing Filter,其实也是Pre Filter。
- Zuul2在代码中显示得提供了InboundFilter(负责进来的请求)、OutboundFilter(负责出去的响应)、ProxyEndpoint(负责请求到Origin,串起Inbound和Outbound)。
下面是SCG的Pre Filter(裁剪自官方例子 12.2 Writing Custom GatewayFilter Factories ):
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory { @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { // business logic return chain.filter(); }; } }
Post Filter的例子:
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory { @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { return chain.filter(exchange).then(/* business logic */); }; } }
在Zuul2里,你则得分别实现 HttpInboundSyncFilter
和 HttpOutboundSyncFilter
, ProxyEndpoint
不需要你自己实现。
SCG Filter的问题
SCG的优点很明显,它做了Zuul2不做的事情:
- 替你决定进来的请求转发到哪个Origin。在Zuul2里这个交给你自己来实现。
- 在配置上就决定了这个Route会应用哪些Filter。在Zuul2里这个交给你自己来判断。
但是随着对SCG的深入了解,发现了关于Filter的执行顺序存在一些坑,如果不了解清楚会容易出错。
Filter的排序
前面讲了,SCG在执行过程中Global Filter和Route Filter是一起执行的,那么它们的order是怎样的?
先来看看Global Filter,你可以访问 /actuator/gateway/globalfilters
(见 文档 )得到Global Filter的排序:
那么如果你写了一个自定义 Global Filter,那么它的order是什么呢?这个要看情况:
- 如果你的自定义Global Filter实现了
Ordered
接口或者写了@Order
注解,那么它的order就是它自己设定的值 - 否则,它就没有order
关于这点可以看 FilteringWebHandler.java的源代码 。
再来看看Route Filter,这也分两种情况:
- 如果RouteFilter实现了
Ordered
接口或者写了@Order
注解,那么它的order就是它自己设定的值。 - 否则,它的order则是从1开始,按照Route中定义的顺序依次排序。
关于这点可以看 RouteDefinitionRouteLocator.java的源代码 。
最后SCG把它们两个结合起来,做一个排序,对于没有order的Filter,它的order则默认为 Ordered.LOWEST_PRECEDENCE
。关于这点可以看 FilteringWebHandler.java的源代码 。
用一张图做总结:
Filter的执行顺序
先看SCG文档 3. How It Works 中的这张图:
这张图大概告诉你了SCG的调用过程,可以看到经过了一堆Filters,但是并没有告诉你Filter的执行顺序。然后在SCG的 6.1 Combined Global Filter and GatewayFilter Ordering 提到了:
As Spring Cloud Gateway distinguishes between “pre” and “post” phases for filter logic execution (see: How It Works), the filter with the highest precedence will be the first in the “pre”-phase and the last in the “post”-phase.
也就是说意思如果这个Filter是Pre Filter,那么执行顺序和排序顺序相同,如果这个Filter是Post Filter则执行顺序和排序顺序相反。我整理了一下SCG自带GlobalFilter的执行顺序:
可以看到GatewayMetricsFilter既是Pre Filter也是Post Filter。
总结
- 执行某个Route的时候,SCG会将Global Filter和Route Filter结合起来并排序:
- 没有给order的Global Filter则保持order为null去排序
- 没有给order的Route Filter的order则从1开始,根据Route中定义的顺序给值
- 排序逻辑见 AnnotationAwareOrderComparator
- 对于Pre Filter,执行顺序同排序顺序
- 对于Post Filter,执行顺序与排序顺序相反
- 如果你要自定义Global Filter,那么一般来说:
- 自定义的Global Pre Filter要在Routing Filter之前执行
- 自定义的Global Post Filter要在Routing Filter之后执行或者NettyWriteResponseFilter之后执行
- 如果你要自定义Route Filter,那么一般来说:
- 自定义Route Pre Filter要在
ForwardPathFilter
和RouteToRequestUrlFilter
之间,而且不需要实现Ordered
接口或添加@Order
注解 - 自定义的Route Post Filter比较少见,放在Routing Filter或者NettyWriteResponseFilter之后执行
- 自定义Route Pre Filter要在
以上所述就是小编给大家介绍的《理解Spring Cloud Gateway Filters的执行顺序》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 深入理解 RocketMQ 普通消息和顺序消息使用,原理,优化
- 【译】Effective TensorFlow Chapter7——理解执行顺序和控制依赖
- ViewGroup 默认顺序绘制子 View,如何修改?什么场景需要修改绘制顺序?
- JavaScript万物产生顺序
- SpringBoot配置加载顺序
- SQL语句执行顺序详解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数据结构、算法与应用(原书第2版)
Sartaj Sahni / 王立柱、刘志红 / 机械工业出版社 / 2015-4 / 79.00元
《数据结构、算法与应用——C++语言描述》是享有盛誉的数据结构教科书的第2版。它完整地包含了基本数据结构的内容,是CS2课程的理想用书。作者Sartaj Sahni通过循循善诱的讲解、直观具体的讨论和基于现实的应用,让读者轻松、愉快地学习。新版书着重利用标准模板库(STL),把书中开发的数据结构和算法与相应的STL实现方法相互关联。本书还增加了很多新的实例和练习题。 书中的应用实例是它的特色......一起来看看 《数据结构、算法与应用(原书第2版)》 这本书的介绍吧!