spring cloud gateway 原始碼解析(1)整體流程

彈肖邦の夜曲發表於2019-01-19

公司要做自己的閘道器,於是先把github的issue過了一遍,然後把gateway原始碼在看了一遍,這樣公司的需求就搞定了。包括動態路由,多緯度限流,記錄請求引數及返回引數(也可修改)。先從請求進入閘道器說起吧:
請求先進入HttpWebHandlerAdapter 類裡

@Override
    public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
        ServerWebExchange exchange = createExchange(request, response);
        //getDelegate()獲取的是ExceptionHandlingWebHandler,用來處理全域性的異常
        return getDelegate().handle(exchange)
                .onErrorResume(ex -> handleFailure(request, response, ex))
                .then(Mono.defer(response::setComplete));
    }

    protected ServerWebExchange createExchange(ServerHttpRequest request, ServerHttpResponse response) {
//這裡的DefaultServerWebExchange就是後面過濾器用到的ServerWebExchange,包括封裝的請求引數,以及再執行過濾器時往裡面新增引數,引數是執行緒安全的
        return new DefaultServerWebExchange(request, response, this.sessionManager,
                getCodecConfigurer(), getLocaleContextResolver(), this.applicationContext);
    }

往下走:

前面的getDelegate().handle(exchange)進入DefaultWebFilterChain類裡

public class DefaultWebFilterChain implements WebFilterChain {

    private final List<WebFilter> filters;

    private final WebHandler handler;

    private final int index;

    ·······

    @Override
    public Mono<Void> filter(ServerWebExchange exchange) {
        return Mono.defer(() -> {
            if (this.index < this.filters.size()) {//先執行完所有的 WebFilter 
                WebFilter filter = this.filters.get(this.index);
                //這裡重新new DefaultWebFilterChain然後呼叫filter方法,也就會順序執行所有的過濾器了
                WebFilterChain chain = new DefaultWebFilterChain(this, this.index + 1);
                return filter.filter(exchange, chain);
            }
            else {//然後才會執行閘道器自定義的過濾器
                return this.handler.handle(exchange);
            }
        });
    }

}

往下:

this.handler.handle(exchange),進入到DispatcherHandler類裡

public class DispatcherHandler implements WebHandler, ApplicationContextAware {
    ····
    @Nullable
    //HandlerMapping用來判斷請求進來的地址應該怎麼處理,可能會匹配到spring webflux的HandlerFunction,
    或者是controller,然後才是我們在閘道器配置的路由,都匹配不上的話就到SimpleUrlHandlerMapping來處理404            
    了,這裡其實有點不太明白為什麼作者會把閘道器路由的優先順序設定低於HandlerFunction,controller,閘道器畢竟是            
    用來轉發,所以我另外加了個類設定了最高的優先順序(修改RoutePredicateHandlerMapping中的order)
    private List<HandlerMapping> handlerMappings;

    @Nullable
    private List<HandlerAdapter> handlerAdapters;

    @Nullable
    //處理閘道器呼叫第三方服務返回的結果
    private List<HandlerResultHandler> resultHandlers;
 
     ·····
    public DispatcherHandler(ApplicationContext applicationContext) {
        initStrategies(applicationContext);
    }
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        initStrategies(applicationContext);
    }

    //閘道器啟動時呼叫,設定三個list變數並排序
    protected void initStrategies(ApplicationContext context) {
        Map<String, HandlerMapping> mappingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                context, HandlerMapping.class, true, false);

        ArrayList<HandlerMapping> mappings = new ArrayList<>(mappingBeans.values());
        AnnotationAwareOrderComparator.sort(mappings);
        this.handlerMappings = Collections.unmodifiableList(mappings);

        Map<String, HandlerAdapter> adapterBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                context, HandlerAdapter.class, true, false);

        this.handlerAdapters = new ArrayList<>(adapterBeans.values());
        AnnotationAwareOrderComparator.sort(this.handlerAdapters);

        Map<String, HandlerResultHandler> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                context, HandlerResultHandler.class, true, false);

        this.resultHandlers = new ArrayList<>(beans.values());
        AnnotationAwareOrderComparator.sort(this.resultHandlers);
    }


    @Override
    public Mono<Void> handle(ServerWebExchange exchange) {
        if (logger.isDebugEnabled()) {
            ServerHttpRequest request = exchange.getRequest();
            logger.debug("Processing " + request.getMethodValue() + " request for [" + request.getURI() + "]");
        }
        if (this.handlerMappings == null) {
            return Mono.error(HANDLER_NOT_FOUND_EXCEPTION);
        }
        return Flux.fromIterable(this.handlerMappings)
                //handlerMappings根據路由匹配合適的handler,確定是閘道器處理還是代理到第三方
                .concatMap(mapping -> mapping.getHandler(exchange))
                //上面的匹配可能會出現多個符合條件的,next()的作用在於匹配到第一個就停止匹配
                .next()
                .switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION))
                .flatMap(handler -> invokeHandler(exchange, handler))
                .flatMap(result -> handleResult(exchange, result));
    }

    private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {
        if (this.handlerAdapters != null) {
            for (HandlerAdapter handlerAdapter : this.handlerAdapters) {
                if (handlerAdapter.supports(handler)) {//前面匹配到handler後,迴圈便利是否支援並執行    
                    hadler方法
                    return handlerAdapter.handle(exchange, handler); 
                }
            }
        }
        return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
    }

    private Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
        return getResultHandler(result).handleResult(exchange, result)
                .onErrorResume(ex -> result.applyExceptionHandler(ex).flatMap(exceptionResult ->
                        //同樣是迴圈遍歷是否支援並執行  handleResult方法
                        getResultHandler(exceptionResult).handleResult(exchange, exceptionResult)));
    }

    private HandlerResultHandler getResultHandler(HandlerResult handlerResult) {
        if (this.resultHandlers != null) {
            for (HandlerResultHandler resultHandler : this.resultHandlers) {
                if (resultHandler.supports(handlerResult)) { 
                    return resultHandler;
                }
            }
        }
        throw new IllegalStateException("No HandlerResultHandler for " + handlerResult.getReturnValue());
    }

}

接上面 :

handlerAdapter.handle(exchange, handler); 
只說匹配到我們配置的路由的情況
進入到SimpleHandlerAdapter類
public class SimpleHandlerAdapter implements HandlerAdapter {

    @Override
    public boolean supports(Object handler) {
        return WebHandler.class.isAssignableFrom(handler.getClass());
    }

    @Override
    public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
        WebHandler webHandler = (WebHandler) handler;
        //根據傳進來的不同handler處理不同的情況,匹配上路由的話傳進來的是FilteringWebHandler
        Mono<Void> mono = webHandler.handle(exchange);
        return mono.then(Mono.empty());
    }

}
繼續看FilteringWebHandler類:

public class FilteringWebHandler implements WebHandler {
    protected static final Log logger = LogFactory.getLog(FilteringWebHandler.class);

    private final List<GatewayFilter> globalFilters;
    //在GatewayAutoConfiguration中配置bean,注入所有實現GlobalFilter的類
    public FilteringWebHandler(List<GlobalFilter> globalFilters) {
        this.globalFilters = loadFilters(globalFilters);
    }
    //將GlobalFilter和GatewayFilter合併並排序
    private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
        return filters.stream()
                .map(filter -> {
                    GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
                    if (filter instanceof Ordered) {
                        int order = ((Ordered) filter).getOrder();
                        return new OrderedGatewayFilter(gatewayFilter, order);
                    }
                    return gatewayFilter;
                }).collect(Collectors.toList());
    }

    /* TODO: relocate @EventListener(RefreshRoutesEvent.class)
    void handleRefresh() {
        this.combinedFiltersForRoute.clear();
    }*/

    @Override
    public Mono<Void> handle(ServerWebExchange exchange) {
        //獲取前面在匹配路由時放進ServerWebExchange中的路由資料
        Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
        //獲取本路由配置的過濾器
        List<GatewayFilter> gatewayFilters = route.getFilters();

        List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
        //把當前路由的過濾器跟全域性過濾器組合
        combined.addAll(gatewayFilters);
        //排序
        AnnotationAwareOrderComparator.sort(combined);

        if (logger.isDebugEnabled()) {
            logger.debug("Sorted gatewayFilterFactories: "+ combined);
        }

        return new DefaultGatewayFilterChain(combined).filter(exchange);
    }

    private static class DefaultGatewayFilterChain implements GatewayFilterChain {

        private final int index;
        private final List<GatewayFilter> filters;

        public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
            this.filters = filters;
            this.index = 0;
        }

        private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
            this.filters = parent.getFilters();
            this.index = index;
        }

        public List<GatewayFilter> getFilters() {
            return filters;
        }

        @Override
        public Mono<Void> filter(ServerWebExchange exchange) {
            return Mono.defer(() -> {
                if (this.index < filters.size()) {
                //與之前的WebFilter 一樣,每次執行都new DefaultGatewayFilterChain呼叫filter方法,
                //不斷往下執行直到過濾器走完
                    GatewayFilter filter = filters.get(this.index);
                    DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
                    return filter.filter(exchange, chain);
                } else {
                    return Mono.empty(); // complete
                }
            });
        }
    }

    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();
        }
    }

}

然後,在排序倒數第二的過濾器NettyRoutingFilter中,呼叫預設的HttpClient,代理到後面的服務。
至此,流程就走完了。

相關文章