Spring Cloud – Ribbon

重構地球發表於2018-01-26

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

    };
    }

 }







相關文章