Netflix Feign - Spring Cloud 整合 Feign 源码(十)

230 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


根据参数【argv】通过请求模版工厂【RequestTemplate.Factory】获取请求模版

/**
 * SynchronousMethodHandler & MethodHander
 *
 */
@Override
public Object invoke(Object[] argv) throws Throwable {
    // 根据参数【argv】通过请求模版工厂【RequestTemplate.Factory】获取请求模版【RequestTemplate】
    RequestTemplate template = buildTemplateFromArgs.create(argv);
    Options options = findOptions(argv);
    Retryer retryer = this.retryer.clone();
    while (true) {
        try {
            // 执行并且解码
            return executeAndDecode(template, options);
        } catch (RetryableException e) {
            try {
                retryer.continueOrPropagate(e);
            } catch (RetryableException th) {
                Throwable cause = th.getCause();
                if (propagationPolicy == UNWRAP && cause != null) {
                    throw cause;
                } else {
                    throw th;
                }
            }
            if (logLevel != Logger.Level.NONE) {
                logger.logRetry(metadata.configKey(), logLevel);
            }
            continue;
        }
    }
}
/**
 *
 */
Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
    // RequestTemplate 遍历应用 RequestInterceptor
    // target.apply(template)获取Request
    Request request = targetRequest(template);

    if (logLevel != Logger.Level.NONE) {
        logger.logRequest(metadata.configKey(), logLevel, request);
    }

    Response response;
    long start = System.nanoTime();
    try {
        // LoadBalancerFeignClient#execute(request,options)
        // Feign整合Ribbon
        response = client.execute(request, options);
    } catch (IOException e) {
        if (logLevel != Logger.Level.NONE) {
            logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime(start));
        }
        throw errorExecuting(request, e);
    }
    // Response 处理相关。。。省略暂时不分析。
}
/**
 * LoadBalancerFeignClient & Client
 */
@Override
public Response execute(Request request, Request.Options options) throws IOException {
    try {
        URI asUri = URI.create(request.url());
        String clientName = asUri.getHost();
        URI uriWithoutHost = cleanUrl(request.url(), clientName);
        // 整合Ribbon。
        FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(
            this.delegate, request, uriWithoutHost);

        IClientConfig requestConfig = getClientConfig(options, clientName);
        // lbClient:从CachingSpringLoadBalancerFactory工厂获取clientName对应的FeignLoadBalancer
        // executeWithLoadBalancer:根据FeignLoadBalacer.RibbonRequest获取FeignLoadBalancer.RibbonRespronse
        // toResponse:FeignLoadBalancer.RibbonRespronse中返回Response
        return lbClient(clientName)
            .executeWithLoadBalancer(ribbonRequest, requestConfig).toResponse();
    }
    catch (ClientException e) {
        IOException io = findIOException(e);
        if (io != null) {
            throw io;
        }
        throw new RuntimeException(e);
    }
}
/**
 * AbstractLoadBalancerAwareClient#executeWithLoadBalancer
 * FeignLoadBalancer
 */
public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {
    // 构造。。。
    LoadBalancerCommand<T> command = buildLoadBalancerCommand(request, requestConfig);

    try {
        // LoadBalancerCommand.submit:返回Observable<FeignLoadBalancer.RibbonResponse>对象
        // 构造一个匿名对象【ServerOperation】作为submit方法的参数,构造Observable<FeignLoadBalancer.RibbonResponse>对象。
        return command.submit(
            new ServerOperation<T>() {
                @Override
                public Observable<T> call(Server server) {
                    URI finalUri = reconstructURIWithServer(server, request.getUri());
                    S requestForServer = (S) request.replaceUri(finalUri);
                    try {
                        return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));
                    } 
                    catch (Exception e) {
                        return Observable.error(e);
                    }
                }
            })
            // toBlocking:使用BlockingObservable封装Observable,返回BlockingObservable类型的对象。【适配器模式?】
            .toBlocking()
            // single:BlockingObservable内部的方法。
            .single();
    } catch (Exception e) {
        Throwable t = e.getCause();
        if (t instanceof ClientException) {
            throw (ClientException) t;
        } else {
            throw new ClientException(e);
        }
    }

}
/**
 *
 */
public Observable<T> submit(final ServerOperation<T> operation) {
    final ExecutionInfoContext context = new ExecutionInfoContext();

    if (listenerInvoker != null) {
        try {
            listenerInvoker.onExecutionStart();
        } catch (AbortExecutionException e) {
            return Observable.error(e);
        }
    }

    final int maxRetrysSame = retryHandler.getMaxRetriesOnSameServer();
    final int maxRetrysNext = retryHandler.getMaxRetriesOnNextServer();

    // Use the load balancer
    Observable<T> o = 
        // LoadBalancerCommand<T> command = buildLoadBalancerCommand(request, requestConfig);
        // 构造command时,并没有指定server,所以此时会调用selectServer()方法返回server
        (server == null ? selectServer() : Observable.just(server))
        // concatMap:返回Observable<FeignLoadBalancer.RibbonResponse>。Func1类型的匿名对象作为参数。
        .concatMap(new Func1<Server, Observable<T>>() {
            @Override
            // Called for each server being selected
            public Observable<T> call(Server server) {
                context.setServer(server);
                final ServerStats stats = loadBalancerContext.getServerStats(server);

                // Called for each attempt and retry
                Observable<T> o = Observable
                    .just(server)
                    .concatMap(new Func1<Server, Observable<T>>() {
                        @Override
                        public Observable<T> call(final Server server) {
                            context.incAttemptCount();
                            loadBalancerContext.noteOpenConnection(stats);

                            if (listenerInvoker != null) {
                                try {
                                    listenerInvoker.onStartWithServer(context.toExecutionInfo());
                                } catch (AbortExecutionException e) {
                                    return Observable.error(e);
                                }
                            }

                            final Stopwatch tracer = loadBalancerContext.getExecuteTracer().start();

                            return operation.call(server).doOnEach(new Observer<T>() {
                                private T entity;
                                @Override
                                public void onCompleted() {
                                    recordStats(tracer, stats, entity, null);
                                    // TODO: What to do if onNext or onError are never called?
                                }

                                @Override
                                public void onError(Throwable e) {
                                    recordStats(tracer, stats, null, e);
                                    logger.debug("Got error {} when executed on server {}", e, server);
                                    if (listenerInvoker != null) {
                                        listenerInvoker.onExceptionWithServer(e, context.toExecutionInfo());
                                    }
                                }

                                @Override
                                public void onNext(T entity) {
                                    this.entity = entity;
                                    if (listenerInvoker != null) {
                                        listenerInvoker.onExecutionSuccess(entity, context.toExecutionInfo());
                                    }
                                }                            

                                private void recordStats(Stopwatch tracer, ServerStats stats, Object entity, Throwable exception) {
                                    tracer.stop();
                                    loadBalancerContext.noteRequestCompletion(stats, entity, exception, tracer.getDuration(TimeUnit.MILLISECONDS), retryHandler);
                                }
                            });
                        }
                    });

                if (maxRetrysSame > 0) 
                    o = o.retry(retryPolicy(maxRetrysSame, true));
                return o;
            }
        });

    if (maxRetrysNext > 0 && server == null) 
        o = o.retry(retryPolicy(maxRetrysNext, false));

    // onErrorResumeNext:返回Observable<FeignLoadBalancer.RibbonResponse>。Func1类型的匿名对象作为参数。
    return o.onErrorResumeNext(new Func1<Throwable, Observable<T>>() {
        @Override
        public Observable<T> call(Throwable e) {
            if (context.getAttemptCount() > 0) {
                if (maxRetrysNext > 0 && context.getServerAttemptCount() == (maxRetrysNext + 1)) {
                    e = new ClientException(ClientException.ErrorType.NUMBEROF_RETRIES_NEXTSERVER_EXCEEDED,
                                            "Number of retries on next server exceeded max " + maxRetrysNext
                                            + " retries, while making a call for: " + context.getServer(), e);
                }
                else if (maxRetrysSame > 0 && context.getAttemptCount() == (maxRetrysSame + 1)) {
                    e = new ClientException(ClientException.ErrorType.NUMBEROF_RETRIES_EXEEDED,
                                            "Number of retries exceeded max " + maxRetrysSame
                                            + " retries, while making a call for: " + context.getServer(), e);
                }
            }
            if (listenerInvoker != null) {
                listenerInvoker.onExecutionFailed(e, context.toFinalExecutionInfo());
            }
            return Observable.error(e);
        }
    });
}
private Observable<Server> selectServer() {
    // 以Observable为参数调用create方法,构造Observable对象。
    // Observable.OnSubscribe<Server>
    return Observable.create(new OnSubscribe<Server>() {
        @Override
        public void call(Subscriber<? super Server> next) {
            try {
                // 根据loadBalancerKey调用ILoadBalancer.chooseServer()方法选择Server。
                Server server = loadBalancerContext.getServerFromLoadBalancer(loadBalancerURI, loadBalancerKey);   
                next.onNext(server);
                next.onCompleted();
            } catch (Exception e) {
                next.onError(e);
            }
        }
    });
}
/**
 * 构造Observable对象
 */
public final <R> Observable<R> concatMap(Func1<? super T, ? extends Observable<? extends R>> func) {
    if (this instanceof ScalarSynchronousObservable) {
        ScalarSynchronousObservable<T> scalar = (ScalarSynchronousObservable)this;
        return scalar.scalarFlatMap(func);
    } else {
        return unsafeCreate(new OnSubscribeConcatMap(this, func, 2, 0));
    }
}