共计 4510 个字符,预计需要花费 12 分钟才能阅读完成。
序
本文主要研究一下 spring cloud 的 CachingSpringLoadBalancerFactory
CachingSpringLoadBalancerFactory
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/CachingSpringLoadBalancerFactory.java
public class CachingSpringLoadBalancerFactory {
protected final SpringClientFactory factory;
protected LoadBalancedRetryFactory loadBalancedRetryFactory = null;
private volatile Map<String, FeignLoadBalancer> cache = new ConcurrentReferenceHashMap<>();
public CachingSpringLoadBalancerFactory(SpringClientFactory factory) {this.factory = factory;}
public CachingSpringLoadBalancerFactory(SpringClientFactory factory,
LoadBalancedRetryFactory loadBalancedRetryPolicyFactory) {
this.factory = factory;
this.loadBalancedRetryFactory = loadBalancedRetryPolicyFactory;
}
public FeignLoadBalancer create(String clientName) {FeignLoadBalancer client = this.cache.get(clientName);
if (client != null) {return client;}
IClientConfig config = this.factory.getClientConfig(clientName);
ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
ServerIntrospector serverIntrospector = this.factory.getInstance(clientName,
ServerIntrospector.class);
client = this.loadBalancedRetryFactory != null
? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
this.loadBalancedRetryFactory)
: new FeignLoadBalancer(lb, config, serverIntrospector);
this.cache.put(clientName, client);
return client;
}
}
- CachingSpringLoadBalancerFactory 的构造器接收 SpringClientFactory、LoadBalancedRetryFactory;它提供了 create 方法用于创建 FeignLoadBalancer;其 create 方法使用 ConcurrentReferenceHashMap 来缓存每个 client 对应的 FeignLoadBalancer
LoadBalancerFeignClient
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/LoadBalancerFeignClient.java
public class LoadBalancerFeignClient implements Client {static final Request.Options DEFAULT_OPTIONS = new Request.Options();
private final Client delegate;
private CachingSpringLoadBalancerFactory lbClientFactory;
private SpringClientFactory clientFactory;
public LoadBalancerFeignClient(Client delegate,
CachingSpringLoadBalancerFactory lbClientFactory,
SpringClientFactory clientFactory) {
this.delegate = delegate;
this.lbClientFactory = lbClientFactory;
this.clientFactory = clientFactory;
}
static URI cleanUrl(String originalUrl, String host) {
String newUrl = originalUrl;
if (originalUrl.startsWith("https://")) {newUrl = originalUrl.substring(0, 8)
+ originalUrl.substring(8 + host.length());
}
else if (originalUrl.startsWith("http")) {newUrl = originalUrl.substring(0, 7)
+ originalUrl.substring(7 + host.length());
}
StringBuffer buffer = new StringBuffer(newUrl);
if ((newUrl.startsWith("https://") && newUrl.length() == 8)
|| (newUrl.startsWith("http://") && newUrl.length() == 7)) {buffer.append("/");
}
return URI.create(buffer.toString());
}
@Override
public Response execute(Request request, Request.Options options) throws IOException {
try {URI asUri = URI.create(request.url());
String clientName = asUri.getHost();
URI uriWithoutHost = cleanUrl(request.url(), clientName);
FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(this.delegate, request, uriWithoutHost);
IClientConfig requestConfig = getClientConfig(options, clientName);
return lbClient(clientName)
.executeWithLoadBalancer(ribbonRequest, requestConfig).toResponse();}
catch (ClientException e) {IOException io = findIOException(e);
if (io != null) {throw io;}
throw new RuntimeException(e);
}
}
IClientConfig getClientConfig(Request.Options options, String clientName) {
IClientConfig requestConfig;
if (options == DEFAULT_OPTIONS) {requestConfig = this.clientFactory.getClientConfig(clientName);
}
else {requestConfig = new FeignOptionsClientConfig(options);
}
return requestConfig;
}
protected IOException findIOException(Throwable t) {if (t == null) {return null;}
if (t instanceof IOException) {return (IOException) t;
}
return findIOException(t.getCause());
}
public Client getDelegate() {return this.delegate;}
private FeignLoadBalancer lbClient(String clientName) {return this.lbClientFactory.create(clientName);
}
static class FeignOptionsClientConfig extends DefaultClientConfigImpl {FeignOptionsClientConfig(Request.Options options) {
setProperty(CommonClientConfigKey.ConnectTimeout,
options.connectTimeoutMillis());
setProperty(CommonClientConfigKey.ReadTimeout, options.readTimeoutMillis());
}
@Override
public void loadProperties(String clientName) { }
@Override
public void loadDefaultValues() {}
}
}
- LoadBalancerFeignClient 的 lbClient 方法使用 CachingSpringLoadBalancerFactory 的 create 方法来创建 FeignLoadBalancer;而 execute 方法则调用了 lbClient 方法来获取 FeignLoadBalancer
小结
CachingSpringLoadBalancerFactory 的构造器接收 SpringClientFactory、LoadBalancedRetryFactory;它提供了 create 方法用于创建 FeignLoadBalancer;其 create 方法使用 ConcurrentReferenceHashMap 来缓存每个 client 对应的 FeignLoadBalancer
doc
- CachingSpringLoadBalancerFactory
正文完
发表至:无分类
2019-07-22