FeignRibbonClientAutoConfiguration.javajava
@ConditionalOnClass({ILoadBalancer.class, Feign.class}) @Configuration @AutoConfigureBefore({FeignAutoConfiguration.class}) @EnableConfigurationProperties({FeignHttpClientProperties.class}) @Import({HttpClientFeignLoadBalancedConfiguration.class, OkHttpFeignLoadBalancedConfiguration.class, DefaultFeignLoadBalancedConfiguration.class}) public class FeignRibbonClientAutoConfiguration { public FeignRibbonClientAutoConfiguration() { } @Bean @Primary @ConditionalOnMissingBean @ConditionalOnMissingClass({"org.springframework.retry.support.RetryTemplate"}) public CachingSpringLoadBalancerFactory cachingLBClientFactory(SpringClientFactory factory) { return new CachingSpringLoadBalancerFactory(factory); } @Bean @Primary @ConditionalOnMissingBean @ConditionalOnClass( name = {"org.springframework.retry.support.RetryTemplate"} ) public CachingSpringLoadBalancerFactory retryabeCachingLBClientFactory(SpringClientFactory factory, LoadBalancedRetryFactory retryFactory) { return new CachingSpringLoadBalancerFactory(factory, retryFactory); } @Bean @ConditionalOnMissingBean public Options feignRequestOptions() { return LoadBalancerFeignClient.DEFAULT_OPTIONS; } }
<dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
配置文件中:spring
feign.httpclient.enabled=true網絡
重新啓動便可(具體看源碼進行分析)負載均衡
LoadBalancerFeignClient.java框架
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); } } }
execute執行請求的方法ui
public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException { LoadBalancerCommand command = this.buildLoadBalancerCommand(request, requestConfig); 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 var6) { Throwable t = var6.getCause(); if (t instanceof ClientException) { throw (ClientException)t; } else { throw new ClientException(var6); } } }
public Observable<T> submit(final ServerOperation<T> operation) { final LoadBalancerCommand<T>.ExecutionInfoContext context = new LoadBalancerCommand.ExecutionInfoContext(); if (this.listenerInvoker != null) { try { this.listenerInvoker.onExecutionStart(); } catch (AbortExecutionException var6) { return Observable.error(var6); } } final int maxRetrysSame = this.retryHandler.getMaxRetriesOnSameServer(); final int maxRetrysNext = this.retryHandler.getMaxRetriesOnNextServer(); 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); ......
上述代碼中有一個selectServe()方法:該方法就是選擇服務進行負載均衡的方法this
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來處理url