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返回的攔截器app
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); } }; } }