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方法
@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行,代码如下所示:
@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行,代码如下所示
@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链
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执行
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链设计,以及启动装在流程等。