LoadBalancerAutoConfiguration 定制个性化的restTemplate
@Bean
public SmartInitializingSingleton loadBalancedRestTemplateInitializer (
final List<RestTemplateCustomizer> customizers) {
return new SmartInitializingSingleton() {
@Override
public void afterSingletonsInstantiated () {
for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this .restTemplates) {
for (RestTemplateCustomizer customizer : customizers) {
customizer.customize(restTemplate);
}
}
}
};
}
@Bean
@ConditionalOnMissingBean
public RestTemplateCustomizer restTemplateCustomizer (
final RetryLoadBalancerInterceptor loadBalancerInterceptor) {
return new RestTemplateCustomizer() {
@Override
public void customize (RestTemplate restTemplate) {
List<ClientHttpRequestInterceptor> list = new ArrayList<>(
restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
}
};
}
@Bean
public LoadBalancerInterceptor ribbonInterceptor (
LoadBalancerClient loadBalancerClient,
LoadBalancerRequestFactory requestFactory) {
return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
}
LoadBalancerInterceptor#intercept
@Override
public ClientHttpResponse intercept (final HttpRequest request, final byte [] body,
final ClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
Assert.state(serviceName != null , "Request URI does not contain a valid hostname: " + originalUri);
return this .loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
}
ILoadBalancer 负载均衡
DynamicServerListLoadBalancer ,BaseLoadBalancer
@Override
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
Server server = getServer(loadBalancer);
if (server == null ) {
throw new IllegalStateException("No instances available for " + serviceId);
}
RibbonServer ribbonServer = new RibbonServer(serviceId, server , isSecure(server ,
serviceId), serverIntrospector(serviceId).getMetadata(server ));
return execute(serviceId, ribbonServer, request);
}
主要由IRule 来负载选择server
public Server chooseServer (Object key) {
if (counter == null ) {
counter = createCounter();
}
counter.increment();
if (rule == null ) {
return null ;
} else {
try {
return rule.choose(key);
} catch (Exception e) {
logger.warn("LoadBalancer [{}]: Error choosing server for key {}" , name, key, e);
return null ;
}
}
}