FeignRibbonClientAutoConfiguration类配置了client.default的类型(包括HttpURLConnection、OkHttp和HttpClient),最终向容器注入的是Client的实现类LoadBalancerFeignClient,即负载均衡客户端。查看LoadalancerFeignClient类中的execute方法,即执行请求的方法,代码如下:
public Response execute(Request request, Options options) throws IOException {
try {
URI asUri = URI.create(request.url());
String clientName = asUri.getHost();
URI uriWithoutHost = cleanUrl(request.url(), clientName);
RibbonRequest ribbonRequest = new RibbonRequest(this.delegate, request, uriWithoutHost);
IClientConfig requestConfig = this.getClientConfig(options, clientName);
return ((RibbonResponse)this.lbClient(clientName).executeWithLoadBalancer(ribbonRequest, requestConfig)).toResponse();
} catch (ClientException var8) {
IOException io = this.findIOException(var8);
if (io != null) {
throw io;
} else {
throw new RuntimeException(var8);
}
}
}
其中有一个executeWithLoadBalancer()方法,即通过负载均衡的方式来执行网络请求,代码如下:
public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {
RequestSpecificRetryHandler handler = this.getRequestSpecificRetryHandler(request, requestConfig);
LoadBalancerCommand command = LoadBalancerCommand.builder().withLoadBalancerContext(this).withRetryHandler(handler).withLoadBalancerURI(request.getUri()).build();
try {
return (IResponse)command.submit(new ServerOperation<T>() {
public Observable<T> call(Server server) {
URI finalUri = AbstractLoadBalancerAwareClient.this.reconstructURIWithServer(server, request.getUri());
ClientRequest requestForServer = request.replaceUri(finalUri);
try {
return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));
} catch (Exception var5) {
return Observable.error(var5);
}
}
}).toBlocking().single();
} catch (Exception var7) {
Throwable t = var7.getCause();
if (t instanceof ClientException) {
throw (ClientException)t;
} else {
throw new ClientException(var7);
}
}
}
在上述代码中,有一个submit()方法,进入submit()方法的内部可以看出它是LoadBalancerCommand类的方法,代码如下:
Observable<T> o = (this.server == null ? this.selectServer() : Observable.just(this.server)).concatMap(new Func1<Server, Observable<T>>() {
public Observable<T> call(Server server) {
context.setServer(server);
final ServerStats stats = LoadBalancerCommand.this.loadBalancerContext.getServerStats(server);
Observable<T> o = Observable.just(server).concatMap(new Func1<Server, Observable<T>>() {
public Observable<T> call(final Server server) {
context.incAttemptCount();
LoadBalancerCommand.this.loadBalancerContext.noteOpenConnection(stats);
if (LoadBalancerCommand.this.listenerInvoker != null) {
try {
LoadBalancerCommand.this.listenerInvoker.onStartWithServer(context.toExecutionInfo());
} catch (AbortExecutionException var3) {
return Observable.error(var3);
}
}
final Stopwatch tracer = LoadBalancerCommand.this.loadBalancerContext.getExecuteTracer().start();
return operation.call(server).doOnEach(new Observer<T>() {
private T entity;
public void onCompleted() {
this.recordStats(tracer, stats, this.entity, (Throwable)null);
}
public void onError(Throwable e) {
this.recordStats(tracer, stats, (Object)null, e);
LoadBalancerCommand.logger.debug("Got error {} when executed on server {}", e, server);
if (LoadBalancerCommand.this.listenerInvoker != null) {
LoadBalancerCommand.this.listenerInvoker.onExceptionWithServer(e, context.toExecutionInfo());
}
}
public void onNext(T entity) {
this.entity = entity;
if (LoadBalancerCommand.this.listenerInvoker != null) {
LoadBalancerCommand.this.listenerInvoker.onExecutionSuccess(entity, context.toExecutionInfo());
}
}
private void recordStats(Stopwatch tracerx, ServerStats statsx, Object entity, Throwable exception) {
tracerx.stop();
LoadBalancerCommand.this.loadBalancerContext.noteRequestCompletion(statsx, entity, exception, tracerx.getDuration(TimeUnit.MILLISECONDS), LoadBalancerCommand.this.retryHandler);
}
});
}
});
if (maxRetrysSame > 0) {
o = o.retry(LoadBalancerCommand.this.retryPolicy(maxRetrysSame, true));
}
return o;
}
});
if (maxRetrysNext > 0 && this.server == null) {
o = o.retry(this.retryPolicy(maxRetrysNext, false));
}
在上述代码中,有一个selectServe()方法,该方法是选择服务进行负载均衡的方法,代码如下:
private Observable<Server> selectServer() {
return Observable.create(new OnSubscribe<Server>() {
public void call(Subscriber<? super Server> next) {
try {
Server server = LoadBalancerCommand.this.loadBalancerContext.getServerFromLoadBalancer(LoadBalancerCommand.this.loadBalancerURI, LoadBalancerCommand.this.loadBalancerKey);
next.onNext(server);
next.onCompleted();
} catch (Exception var3) {
next.onError(var3);
}
}
});
}
由上术代码可知,最终负载均衡交给loadBalancerContext来处理,即上一章讲述的Ribbon,这里不再重复。
总的来说,Feign的源码实现过程如下。