1

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

    };
    }

 }








重构地球
68 声望4 粉丝

rust-zero