摘要:在代碼中顯示得提供了負責進來的請求負責出去的響應負責請求到,串起和。但是隨著對的深入了解,發現了關于的執行順序存在一些坑,如果不了解清楚會容易出錯。否則,它的則是從開始,按照中定義的順序依次排序。我整理了一下自帶的執行順序可以看到既是也是。
本文基于Spring Cloud Gateway 2.1.1.RELEASE。
在講SCG的Filter的排序問題之前得先比較一下Spring Cloud Gateway在對待Filter的方面與Zuul2有著哪些不同。
Filter的ScopeSCG采用的是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之后執行
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74243.html
摘要:歡迎訪問我的歡迎訪問我的內容所有原創文章分類匯總及配套源碼,涉及等本篇概覽本篇概覽作為實戰系列的第五篇,是時候了解過濾器的作用了,本篇咱們一起來了解內置好的過濾器,真是種類繁多功能強大過濾器顧名思義,就是在請求頭部添加指定的內容帶有的完整配歡迎訪問我的GitHubhttps://github.com/zq2599/blog_demos內容:所有原創文章分類匯總及配套源碼,涉及Java、Doc...
摘要:公司要做自己的網關,于是先把的過了一遍,然后把源碼在看了一遍,這樣公司的需求就搞定了。包括動態路由,多緯度限流,記錄請求參數及返回參數也可修改。至此,流程就走完了。 公司要做自己的網關,于是先把github的issue過了一遍,然后把gateway源碼在看了一遍,這樣公司的需求就搞定了。包括動態路由,多緯度限流,記錄請求參數及返回參數(也可修改)。先從請求進入網關說起吧: 請求先進...
摘要:類似的工廠類還有和,,,這幾個就不做單獨講解了,使用方式是一樣的。配置示列配置示列討論時間文章中講的這幾個工廠類的作用我們已經了解了,那具體的使用場景有哪些適合在什么場景下使用呢歡迎大家留言討論。 今天我們來學習下GatewayFilter Factory,中文解釋就是過濾器工廠。 官方文檔對GatewayFilter Factory的介紹: Route filters allow t...
摘要:歡迎訪問我的歡迎訪問我的內容所有原創文章分類匯總及配套源碼,涉及等本篇概覽本篇概覽作為實戰系列的第九篇,咱們聊聊如何用修改原始請求和響應內容,以及修改過程中遇到的問題首先是修改請求,如下圖,瀏覽器是請求發起方,真實參數只有,經過網關時被塞歡迎訪問我的GitHubhttps://github.com/zq2599/blog_demos內容:所有原創文章分類匯總及配套源碼,涉及Java、Dock...
閱讀 4983·2021-11-25 09:43
閱讀 1685·2021-10-27 14:18
閱讀 1057·2021-09-22 16:03
閱讀 1349·2019-08-30 13:19
閱讀 1572·2019-08-30 11:15
閱讀 1645·2019-08-26 14:04
閱讀 3124·2019-08-23 18:40
閱讀 1166·2019-08-23 18:17