RestTemplate
通过添加LoadBalancerInterceptor
拦截器处理请求,LoadBalancerInterceptor
依赖LoadBalancerClient
实现负载均衡,而LoadBalancerClient
实际是委托ILoadBalancer
进行负载均衡逻辑处理。
public class RibbonLoadBalancerClient implements LoadBalancerClient {
//...
private SpringClientFactory clientFactory
@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);
}
protected ILoadBalancer getLoadBalancer(String serviceId) {
return this.clientFactory.getLoadBalancer(serviceId);
}
//...
}
本节将关注ILoadBalancer
对象的初始化,此对象由SpringClientFactory
的父类NamedContextFactory#createContext(String name)
完成初始化。
public class SpringClientFactory extends NamedContextFactory<RibbonClientSpecification> {
//...
static final String NAMESPACE = "ribbon";
public SpringClientFactory() {
super(RibbonClientConfiguration.class, NAMESPACE, "ribbon.client.name");
}
public ILoadBalancer getLoadBalancer(String name) {
return getInstance(name, ILoadBalancer.class);
}
@Override
public <C> C getInstance(String name, Class<C> type) {
C instance = super.getInstance(name, type);
if (instance != null) {
return instance;
}
IClientConfig config = getInstance(name, IClientConfig.class);
return instantiateWithConfig(getContext(name), type, config);
}
@Override
protected AnnotationConfigApplicationContext getContext(String name) {
return super.getContext(name);
}
//...
}
public abstract class NamedContextFactory<C extends NamedContextFactory.Specification>
implements DisposableBean, ApplicationContextAware {
//...
private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();
private Map<String, C> configurations = new ConcurrentHashMap<>();
private Class<?> defaultConfigType;
private final String propertySourceName;
private final String propertyName;
public NamedContextFactory(Class<?> defaultConfigType, String propertySourceName,String propertyName) {
this.defaultConfigType = defaultConfigType;
this.propertySourceName = propertySourceName;
this.propertyName = propertyName;
}
public void setConfigurations(List<C> configurations) {
for (C client : configurations) {
this.configurations.put(client