@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);
}
};
}
}