客户端负载均衡
RestTemplate详解
看一点源码
负载均衡的客户端接口:LoadBalancerClient
public interface LoadBalancerClient {
//根据传入的服务名serviceId,从负载均衡器中挑选一个对应服务的实例
ServiceInstance choose(String var1);
//使用从负载均衡器中挑选出的服务实例来执行请求内容
<T> T execute(String var1, LoadBalancerRequest<T> var2) throws IOException;
//构建合适的host:port形式的URI,参数1,是带有host与port的具体服务实例,参数2,是使用逻辑服务名
//定义为host的URI,返回的是,根据具体服务实例,拼接出的具体的host:post形式的请求地址
URI reconstructURI(ServiceInstance var1, URI var2);
}
客户端负载均衡器的自动化配置类:LoadBalancerAutoConfiguration
@Configuration
//需满足,RestTemplate类必须存在于当前工程环境中
@ConditionalOnClass({
RestTemplate.class})
//需满足,在Spring的Bean工程中必须有LoadBalancerClient的实现Bean
@ConditionalOnBean({
LoadBalancerClient.class})
public class LoadBalancerAutoConfiguration {
@LoadBalanced
@Autowired(
required = false
)
private List<RestTemplate> restTemplates = Collections.emptyList();
public LoadBalancerAutoConfiguration() {
}
//初始化器:维护被@LoadBalanced注解修饰的RestTemplate对象列表,初始化.
//用restTemplateCustomizer的实例来为每个RestTemplate,加拦截器
@Bean
public SmartInitializingSingleton loadBalancedRestTemplateInitializer(final List<RestTemplateCustomizer> customizers) {
return new SmartInitializingSingleton() {
public void afterSingletonsInstantiated() {
//...
}
};
}
//定制化器:为RestTemplate增加LoadBalancerInterceptor拦截器
@Bean
@ConditionalOnMissingBean
public RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {
return new RestTemplateCustomizer() {
public void customize(RestTemplate restTemplate) {
List<ClientHttpRequestInterceptor> list = new ArrayList(restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
}
};
}
//拦截器,在客户端发起请求时,拦截,以实现客户端负载均衡,LoadBalancerInterceptor
//中有个intercept函数拦截请求
@Bean
public LoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient) {
return new LoadBalancerInterceptor(loadBalancerClient);
}
}
负载均衡的实现:RibbonLoadBalancerClient
其中在execute函数中,通过getServer传入服务名,serviceId来获取具体的服务实例,可发现,并没有使用LoadBalancerClient中的choose接口,而是用的Netflix Ribbon 自身地 ILoadBanlencer接口中的chooseServer函数,
protected Server getServer(ILoadBalancer loadBalancer) {
return loadBalancer == null ? null : loadBalancer.chooseServer("default");
}
ILoadBanlencer:定义了一个客户端负载均衡器需要的一系列抽象操作(未列举过期函数