Spring Cloud - Ribbon

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

    };
    }

 }
相關文章
相關標籤/搜索