<>关于SpringCloudGateway与下游的连接分析>
最近面试了不少同学,有很大一部分简历上会提到网关,我一般都会顺着往下问他们的网关是怎么做的。
基本上都是说直接使用的SpringCloudGateway或者基于SpringCloudGateway二次开发。
这种时候我会继续问一个较基础的问题:SpringCloudGateway作为网关,会把接收到的请求转发给下游服务,那么SpringCloudGateway跟下游的服务之间保持的是长连还是短连?还是说每次转发的时候都会新建立一个连接吗?
很遗憾的是,这么基础的问题,很少有面试者完全搞清楚。
所以才有了这篇文章:通过研究SpringCloudGateway的源码,来看看SpringCloudGateway跟下游服务之间是怎么通信的。
SpringCloudGateway
在源码分析之前,需要先了解一下SpringCloudGateway
SpringCloudGateway是SpringCloud的一个全新项目,该项目是基于Spring5.0,Springoot2.0和ProjectReactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的一的API路由方式。
SpringCloudGateway是基于SpringWeFlux框架实现的,而WeFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
SpringCloudGateway架构图如下:
源码分析
对于基于weflux的应用,入口点都在DispatchHandler.handle()方法:
最终执行到SimpleHandlerAdapter.handle()方法
handler()方法中执行的是FilteringWeHandler.handle()方法
FilteringWeHandler.handler()方法的主要逻辑就是依次执行已经形成的全局过滤器gloalFilter的filter()方法。
从截图中可以看到,默认会生成9个全局过滤器GatewayFilter对象。
单步调试下去,发现涉及到网络这一块的作都在倒数第二个过滤器NettyRoutingFilter类中。
现在着重来看一下NettyRoutingFilter.filter()方法:
pulicMono<Void>filter(WeExchangeexchange,GatewayFilterChainchain){
IrequestUrl=exchange.getRequiredAttriute(GATEWAY_REQUEST_L_ATTR);
//...一些省略代码
//获取client
Flux<HttpResponse>responseFlux=getHttp(route,exchange)
.headers(headers->{
headers.add(Headers);
//Willeitheresetelow,orlateryNetty
headers.remove(HttpHeaders.HOST);
if(preserveHost){
Stringhost=request.getHeaders().getFirst(HttpHeaders.HOST);
headers.add(HttpHeaders.HOST,host);
}
}).request(method).i(l).send((req,nettyOutound)->{
if(log.isTraceEnaled()){
nettyOutound
.withConnection(connection->log.trace("outoundroute:"
+connection.channel().id().asShortText()
+",inound:"+exchange.getLogPrefix()));
}
//发送请求
retnnettyOutound.send(request.getody().map(this::getyteuf));
}).responseConnection((res,connection)->{
//省略代码,下游请求返回之后做的一些处理
retnMono.just(res);
});
DationresponseTimeout=getResponseTimeout(route);
//一些省略代码
retnresponseFlux.then(chain.filter(exchange));
}