Spring Cloud Gateway揭秘之处理请求流程

× 文章目录
  1. 1.Spring Gateway概述
  2. 2. Spring Cloud gateway请求入口分析
    1. 2.1 入口HttpServerRequest和HttpServerResponse转换
    2. 2.2 构造Spring Cloud gateway的上下文ServerWebExchange
    3. 2.3 进入Filter链
    4. 2.4 执行Filter链
    5. 2.5 Gateway Filter委托为Gloable Filter执行
    6. 2.6 预告待续

摘要:本篇文章主要从源码的角度揭秘Spring Cloud Gateway的怎么处理请求流程。

1.Spring Gateway概述

Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Netflix ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

2. Spring Cloud gateway请求入口分析

不管是Zuul,还是Spring Cloud Gateway还是基于Netty的自研网关,都会把请求进来的Request,或者返回的Response进行包装,转换提取为网关运行的上下文信息,而在Spring Cloud gateway中网关的上下文为ServerWebExchange。

2.1 入口HttpServerRequest和HttpServerResponse转换

Spring Cloud Gateway的请求入口,org.springframework.http.server.reactive.ReactorHttpHandlerAdapter#apply方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
public Mono<Void> apply(HttpServerRequest request, HttpServerResponse response) {
NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(response.alloc());
ServerHttpRequest adaptedRequest;
ServerHttpResponse adaptedResponse;
try {
adaptedRequest = new ReactorServerHttpRequest(request, bufferFactory);
adaptedResponse = new ReactorServerHttpResponse(response, bufferFactory);
}
catch (URISyntaxException ex) {
logger.error("Invalid URL " + ex.getMessage(), ex);
response.status(HttpResponseStatus.BAD_REQUEST);
return Mono.empty();
}
if (adaptedRequest.getMethod() == HttpMethod.HEAD) {
adaptedResponse = new HttpHeadResponseDecorator(adaptedResponse);
}
return this.httpHandler.handle(adaptedRequest, adaptedResponse)
.doOnError(ex -> logger.error("Handling completed with error", ex))
.doOnSuccess(aVoid -> logger.debug("Handling completed with success"));
}

PS,代码来源于spring-web-5.0.4.RELEASE.jar
此方法为Spring Cloud Gateway的请求入口方法,该方法的作用就是把接收到的HttpServerRequest或者最终需要返回的HttpServerResponse,包装转换为ReactorServerHttpRequest和ReactorServerHttpResponse。

2.2 构造Spring Cloud gateway的上下文ServerWebExchange

在org.springframework.web.server.adapter.HttpWebHandlerAdapter的182行,代码如下所示:

1
2
3
4
5
6
7
@Override
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
ServerWebExchange exchange = createExchange(request, response);
return getDelegate().handle(exchange)
.onErrorResume(ex -> handleFailure(request, response, ex))
.then(Mono.defer(response::setComplete));
}

createExchange()将ServerHttpRequest ServerHttpResponse构建网关上下文ServerWebExchange。


PS:其中org.springframework.web.server.handler.WebHandlerDecorator.getDelegate()通过委托的方式获取一系列需要处理的WebHandler.

2.3 进入Filter链

org.springframework.cloud.gateway.handler.FilteringWebHandler#handle方法,即77行,代码如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
List<GatewayFilter> gatewayFilters = route.getFilters();
List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
combined.addAll(gatewayFilters);
//TODO: needed or cached?
AnnotationAwareOrderComparator.sort(combined);
logger.debug("Sorted gatewayFilterFactories: "+ combined);
return new DefaultGatewayFilterChain(combined).filter(exchange);
}

2.4 执行Filter链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
private int index;
private final List<GatewayFilter> filters;
public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
this.filters = filters;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index++);
return filter.filter(exchange, this);
}
else {
return Mono.empty(); // complete
}
}
}

2.5 Gateway Filter委托为Gloable Filter执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static class GatewayFilterAdapter implements GatewayFilter {
private final GlobalFilter delegate;
public GatewayFilterAdapter(GlobalFilter delegate) {
this.delegate = delegate;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return this.delegate.filter(exchange, chain);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("GatewayFilterAdapter{");
sb.append("delegate=").append(delegate);
sb.append('}');
return sb.toString();
}
}

2.6 预告待续

在之后的文章中,将会揭秘Spring Cloud Gateway的架构设计,Filter链设计,以及启动装在流程等。

如果您觉得文章不错,可以打赏我喝一杯咖啡!