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:進行響應(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:// 前綴過濾處理,做負載均衡,選擇最終要調(diào)用的服務(wù)地址
LoadBalancerServiceInstanceCookieFilter:也是負載均衡相關(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 實現(xiàn)的 HttpClient 請求后端 Http 服務(wù)
ForwardRoutingFilter:轉(zhuǎn)發(fā)路由網(wǎng)關(guān)過濾器。其根據(jù) forward:// 前綴過濾處理,將請求轉(zhuǎn)發(fā)到當(dāng)前網(wǎng)關(guān)實例本地接口。
那么請求最后是怎么轉(zhuǎn)發(fā)到controller那進行處理的呢?
其實是在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)一些其他的擴展知識。
到此這篇關(guān)于SpringCloud Gateway中GatewayFilterChain執(zhí)行流程詳解的文章就介紹到這了,更多相關(guān)SpringCloud GatewayFilterChain內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java8?stream流分組groupingBy的使用方法代碼
對于java8的新特性groupingBy方法,相信有很多人都在工作中用過,這篇文章主要給大家介紹了關(guān)于Java8?stream流分組groupingBy的使用方法,需要的朋友可以參考下2024-01-01
JAVA實現(xiàn)基于Tcp協(xié)議的簡單Socket通信實例
本篇文章主要介紹了JAVA實現(xiàn)基于Tcp協(xié)議的簡單Socket通信實例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01
Java中Collection與Collections的區(qū)別詳解
這篇文章主要為大家詳細介紹了Java中Collection與Collections的區(qū)別,文中有詳細的代碼示例,具有一定的參考價值,感興趣的同學(xué)可以參考一下2023-06-06
Java inputstream和outputstream使用詳解
這篇文章主要介紹了Java inputstream和outputstream使用詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08
Mybatis Plus 字段為空值時執(zhí)行更新方法未更新解決方案

