SpringCloud?Gateway中GatewayFilterChain執(zhí)行流程詳解
上一節(jié)我們把FilteringWebHandler
中handle方法的過濾器統(tǒng)一排序的那部分邏輯講完了
接著就是生成過濾器器鏈,執(zhí)行過濾方法
return new DefaultGatewayFilterChain(combined).filter(exchange);
@Override public Mono<Void> filter(ServerWebExchange exchange) { return Mono.defer(() -> { if (this.index < filters.size()) { //filters就是上面?zhèn)魅氲乃羞^濾器,index就是當(dāng)前的索引 GatewayFilter filter = filters.get(this.index); //index+1,獲取下一個過濾器 DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1); //分別執(zhí)行每個過濾器的filter方法 return filter.filter(exchange, chain); } else { return Mono.empty(); // complete } }); } }
可以看到目前系統(tǒng)內(nèi)置的過濾器有十種,每個過濾器大致的作用我在下面列出來可供參考
RemoveCachedBodyFilter
:移除請求上下文中的body緩存信息,只有在使用了ReadBodyPredicateFactory相關(guān)處理是會有body緩存
AdaptCachedBodyGlobalFilter
:從請求中獲取body緩存到網(wǎng)關(guān)上下文,這樣就可以直接從網(wǎng)關(guān)上下文中拿到請求參數(shù),而不會出現(xiàn)從request中拿到之后還要回填到請求體的問題
NettyWriteResponseFilter
:進(jìn)行響應(yīng)回寫,但是大家可以注意到執(zhí)行器鏈中NettyWriteResponseFilter
的排序是在很前面的,按道理這種響應(yīng)處理的類應(yīng)該是在靠后才對,這里的設(shè)計比較巧妙。大家可以看到chain.filter(exchange).then(),意思就是執(zhí)行到我的時候直接跳過下一個,等后面的過濾器都執(zhí)行完后才執(zhí)行這段邏輯。
ForwardPathFilter
:解析路徑并且將路徑轉(zhuǎn)發(fā)
RouteToRequestUrlFilter
:根據(jù)匹配的 Route ,計算請求的地址
ReactiveLoadBalancerClientFilter
:根據(jù) lb:// 前綴過濾處理,做負(fù)載均衡,選擇最終要調(diào)用的服務(wù)地址
LoadBalancerServiceInstanceCookieFilter
:也是負(fù)載均衡相關(guān),并且和ServiceInstance
有關(guān)
WebsocketRoutingFilter
:Websocket 路由網(wǎng)關(guān)過濾器。其根據(jù) ws://
和 wss://
前綴過濾處理,代理后端 Websocket 服務(wù),提供給客戶端連接
NettyRoutingFilter
:Netty 路由網(wǎng)關(guān)過濾器。其根據(jù) http://
或 https://
前綴過濾處理,使用基于 Netty 實(shí)現(xiàn)的 HttpClient 請求后端 Http 服務(wù)
ForwardRoutingFilter
:轉(zhuǎn)發(fā)路由網(wǎng)關(guān)過濾器。其根據(jù) forward://
前綴過濾處理,將請求轉(zhuǎn)發(fā)到當(dāng)前網(wǎng)關(guān)實(shí)例本地接口。
那么請求最后是怎么轉(zhuǎn)發(fā)到controller那進(jìn)行處理的呢?
其實(shí)是在NettyRoutingFilter
里面,通過httpClient
來發(fā)送request,下面截取一部分代碼
Flux<HttpClientResponse> responseFlux = getHttpClient(route, exchange).headers(headers -> { headers.add(httpHeaders); // Will either be set below, or later by Netty headers.remove(HttpHeaders.HOST); if (preserveHost) { String host = request.getHeaders().getFirst(HttpHeaders.HOST); headers.add(HttpHeaders.HOST, host); } }).request(method).uri(url).send((req, nettyOutbound) -> { if (log.isTraceEnabled()) { nettyOutbound.withConnection(connection -> log.trace("outbound route: " + connection.channel().id().asShortText() + ", inbound: " + exchange.getLogPrefix())); } //具體調(diào)用發(fā)送request的位置 return nettyOutbound.send(request.getBody().map(this::getByteBuf));
Spring-Cloud-Gateway
總體的執(zhí)行流程到這就差不多分享完了,后續(xù)可能繼續(xù)會分享一些關(guān)于路由或者網(wǎng)關(guān)一些其他的擴(kuò)展知識。
到此這篇關(guān)于SpringCloud Gateway中GatewayFilterChain執(zhí)行流程詳解的文章就介紹到這了,更多相關(guān)SpringCloud GatewayFilterChain內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring+Mybatis 實(shí)現(xiàn)aop數(shù)據(jù)庫讀寫分離與多數(shù)據(jù)庫源配置操作
這篇文章主要介紹了Spring+Mybatis 實(shí)現(xiàn)aop數(shù)據(jù)庫讀寫分離與多數(shù)據(jù)庫源配置操作,需要的朋友可以參考下2017-09-09啟動springboot項目時報錯:無法訪問org.springframework.web.bind.annotatio
這篇文章給大家分享了啟動springboot項目時報錯:?無法訪問org.springframework.web.bind.annotation.GetMapping …具有錯誤的版本 61.0,應(yīng)為52.0?的解決方案,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10Spring-Bean創(chuàng)建對象的步驟方式詳解
在本篇文章里小編給大家分享的是關(guān)于Spring-Bean創(chuàng)建對象的步驟方式詳解內(nèi)容,有興趣的朋友們跟著學(xué)習(xí)下。2020-02-02mybatis plus條件構(gòu)造器queryWrapper、updateWrapper
這篇文章主要介紹了mybatis plus條件構(gòu)造器queryWrapper、updateWrapper,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Spring框架中的重要注解及其應(yīng)用代碼實(shí)例
Spring框架廣泛應(yīng)用于多種場景中,下面這篇文章主要給大家介紹了關(guān)于Spring框架中重要注解及其應(yīng)用的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-08-08