上一节我们把FilteringWebHandler
中handle方法的过滤器统一排序的那部分逻辑讲完了
接着就是生成过滤器器链,执行过滤方法
return new DefaultGatewayFilterChain(combined).filter(exchange);
@Override public Mono<Void> filter(ServerWebExchange exchange) { return Mono.defer(() -> { if (this.index < filters.size()) { //filters就是上面传入的所有过滤器,index就是当前的索引 GatewayFilter filter = filters.get(this.index); //index+1,获取下一个过滤器 DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1); //分别执行每个过滤器的filter方法 return filter.filter(exchange, chain); } else { return Mono.empty(); // complete } }); } }
可以看到目前系统内置的过滤器有十种,每个过滤器大致的作用我在下面列出来可供参考
RemoveCachedBodyFilter
:移除请求上下文中的body缓存信息,只有在使用了ReadBodyPredicateFactory相关处理是会有body缓存
AdaptCachedBodyGlobalFilter
:从请求中获取body缓存到网关上下文,这样就可以直接从网关上下文中拿到请求参数,而不会出现从request中拿到之后还要回填到请求体的问题
NettyWriteResponseFilter
:进行响应回写,但是大家可以注意到执行器链中NettyWriteResponseFilter
的排序是在很前面的,按道理这种响应处理的类应该是在靠后才对,这里的设计比较巧妙。大家可以看到chain.filter(exchange).then(),意思就是执行到我的时候直接跳过下一个,等后面的过滤器都执行完后才执行这段逻辑。
ForwardPathFilter
:解析路径并且将路径转发
RouteToRequestUrlFilter
:根据匹配的 Route ,计算请求的地址
ReactiveLoadBalancerClientFilter
:根据 lb:// 前缀过滤处理,做负载均衡,选择最终要调用的服务地址
LoadBalancerServiceInstanceCookieFilter
:也是负载均衡相关,并且和ServiceInstance
有关
WebsocketRoutingFilter
:Websocket 路由网关过滤器。其根据 ws://
和 wss://
前缀过滤处理,代理后端 Websocket 服务,提供给客户端连接
NettyRoutingFilter
:Netty 路由网关过滤器。其根据 http://
或 https://
前缀过滤处理,使用基于 Netty 实现的 HttpClient 请求后端 Http 服务
ForwardRoutingFilter
:转发路由网关过滤器。其根据 forward://
前缀过滤处理,将请求转发到当前网关实例本地接口。
那么请求最后是怎么转发到controller那进行处理的呢?
其实是在NettyRoutingFilter
里面,通过httpClient
来发送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())); } //具体调用发送request的位置 return nettyOutbound.send(request.getBody().map(this::getByteBuf));
Spring-Cloud-Gateway
总体的执行流程到这就差不多分享完了,后续可能继续会分享一些关于路由或者网关一些其他的扩展知识。
到此这篇关于SpringCloud Gateway中GatewayFilterChain执行流程详解的文章就介绍到这了,更多相关SpringCloud GatewayFilterChain内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!