@LoadBalanced
public interface ServiceInstanceChooser {
// 根據傳入的serviceId從LoadBalancer中挑選一個對應的ServiceInstance。
ServiceInstance choose(String serviceId);
}
public interface LoadBalancerClient extends ServiceInstanceChooser {
// 邏輯同choose,即通過ILoadBalancer::chooseServer,然後使用返回的ServiceInstance呼叫下面execute方法。
// ILoadBalancer是負載均衡策略實現,預設由RibbonClientConfiguration::ribbonLoadBalancer生成ZoneAwareLoadBalancer,
<T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
// 根據ServiceInstance來執行請求,呼叫LoadBalancerRequest::apply。
<T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException;
// 將serviceId轉換成host:port(通過註冊中心中各個服務節點的metadata)
URI reconstructURI(ServiceInstance instance, URI original);
}
初始化流程
LoadBalancerAutoConfiguration.LoadBalancerInterceptorConfig
::ribbonInterceptor返回了一個攔截器,作用主要是在客戶端發起請求時進行攔截,進而實現客戶端負載均衡功能。
::restTemplateCustomizer會例項化RestTemplateCustomizer,其作用是設定::ribbonInterceptor返回的攔截器
LoadBalancerAutoConfiguration
::loadBalancedRestTemplateInitializer呼叫RestTemplateCustomizer::customize方法來給RestTemplate新增上LoadBalancerInterceptor攔截器。
執行時流程
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
private LoadBalancerClient loadBalancer;
private LoadBalancerRequestFactory requestFactory;
......
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
// 會調另一個execute方法,即LoadBalancerRequest::apply,而LoadBalancerRequest的例項是由LoadBalancerRequestFactory::createRequest生成的。
return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
}
}
public class LoadBalancerRequestFactory {
......
public LoadBalancerRequest<ClientHttpResponse> createRequest(final HttpRequest request,
final byte[] body, final ClientHttpRequestExecution execution) {
return new LoadBalancerRequest<ClientHttpResponse>() {
@Override
public ClientHttpResponse apply(final ServiceInstance instance)
throws Exception {
// ServiceRequestWrapper重寫了getURI(),即ServiceRequestWrapper::getURI呼叫了LoadBalancerClient::reconstructURI
HttpRequest serviceRequest = new ServiceRequestWrapper(request, instance, loadBalancer);
if (transformers != null) {
for (LoadBalancerRequestTransformer transformer : transformers) {
serviceRequest = transformer.transformRequest(serviceRequest, instance);
}
}
// 這裡的execution是InterceptingRequestExecution::execute,它會呼叫serviceRequest的HttpRequest::getURI,就是上面ServiceRequestWrapper重寫的getURI()
return execution.execute(serviceRequest, body);
}
};
}
}