2018-03-17 · 许进 · · 字数:1382·阅读时间 3 分钟 阅读量

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链设计,以及启动装在流程等。