Ribbon 源码详解(三):负载均衡过程

本文深入解析了Ribbon的负载均衡过程,从`RestTemplate`的使用开始,逐步剖析`doExecute`方法,通过拦截器`LoadBalancerInterceptor`实现负载均衡选择服务。文中详细解释了如何根据服务ID生成Spring容器,获取`ILoadBalancer`并选择服务器,最终执行请求。
摘要由CSDN通过智能技术生成

@Configuration

@RibbonClient(name = "default-test")

public class DefaultConfiguration {

    @Bean

    @LoadBalanced

    public RestTemplate restTemplate() {

        return new RestTemplate();

    }

}

@Service

1、public class DefaultService {

    @Autowired

    private RestTemplate restTemplate;

    public void testDefaultRibbon() {

        String forObject = restTemplate.getForObject("Eureka服务实例ID", String.class);

        System.out.println("**********************");

        System.out.println(forObject);

    }

}

2、(RestTemplate)

protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,

        ResponseExtractor<T> responseExtractor) throws RestClientException {

        ClientHttpResponse response = null;

        try {

                ClientHttpRequest request = createRequest(url, method);//InterceptingClientHttpRequest

                if (requestCallback != null) {

                    requestCallback.doWithRequest(request);

                }

                    response = request.execute();

                    handleResponse(url, method, response);

                if (responseExtractor != null) {

                    return responseExtractor.extractData(response);

                }

}

3、 请求执行 response = request.execute();

-->protected abstract ClientHttpResponse executeInternal(HttpHeaders                         var1);//(AbstractClientHttpRequest)

        -->protected ClientHttpResponse executeInternal(HttpHeaders headers)                            (AbstractBufferingClientHttpRequest)

            -->protected final ClientHttpResponse executeInternal(HttpHeaders headers,                           byte[] bufferedOutput){

                    InterceptingClientHttpRequest.InterceptingRequestExecution                                        requestExecution = new                                                             InterceptingClientHttpRequest.InterceptingRequestExecution();

                    requestExecution.execute(this, bufferedOutput)

                }(InterceptingClientHttpRequest)

4、requestExecution.execute(this, bufferedOutput)

@Override

public ClientHttpResponse execute(HttpRequest request, byte[] body) throws IOException {

            if (this.iterator.hasNext()) {

                //遍历所有的拦截器执行拦截,主要是LoadBalancerInterceptor。

                ClientHttpRequestInterceptor nextInterceptor = this.iterator.next();

                return nextInterceptor.intercept(request, body, this);

            }else {

                //普通调用过程

                ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), request.getMethod());

                for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {

                    List<String> values = entry.getValue();

                    for (String value : values) {

                        delegate.getHeaders().add(entry.getKey(), value);

                    }

                }

                if (body.length > 0) {

                    StreamUtils.copy(body, delegate.getBody());

                }

                return delegate.execute();

           }

}

5、负载均衡拦截器中拦截处理过程。

@Override

public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,

            final ClientHttpRequestExecution execution) throws IOException {

            final URI originalUri = request.getURI();

            String serviceName = originalUri.getHost();

            Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);

            return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));

            ------>requestFactory.createRequest(request, body, execution)

                        -------->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 {

                            HttpRequest serviceRequest = new ServiceRequestWrapper(request, instance, loadBalancer);

                            if (transformers != null) {

                                for (LoadBalancerRequestTransformer transformer : transformers) {

                                serviceRequest = transformer.transformRequest(serviceRequest, instance);

                                }

                            }

                            return execution.execute(serviceRequest, body);

6、@Override//loadBalancer(RibbonLoadBalancerClient)

public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {

        ILoadBalancer loadBalancer = getLoadBalancer(serviceId);

        Server server = getServer(loadBalancer);

        if (server == null) {

            throw new IllegalStateException("No instances available for " + serviceId);

        }

        RibbonServer ribbonServer = new RibbonServer(serviceId, server, isSecure(server,serviceId),                                 serverIntrospector(serviceId).getMetadata(server));

        return execute(serviceId, ribbonServer, request);

}

7、//根据不同的服务ID生成一个Spring容器。采用微服务的名称作为key,容器作为value。如果存在容器则从容器中获取bean,如果不存在直接新生成一个容器,并且进行初始化。  

 ILoadBalancer loadBalancer = getLoadBalancer(serviceId);

protected ILoadBalancer getLoadBalancer(String serviceId) {

        return this.clientFactory.getLoadBalancer(serviceId);

}

(SpringClientFactory)public ILoadBalancer getLoadBalancer(String name) {

    return getInstance(name, ILoadBalancer.class);

}

@Override

public <C> C getInstance(String name, Class<C> type) {

            C instance = super.getInstance(name, type);

            if (instance != null) {

            return instance;

            }

            IClientConfig config = getInstance(name, IClientConfig.class);

            return instantiateWithConfig(getContext(name), type, config);

}

(NamedContextFactory)public <T> T getInstance(String name, Class<T> type) {

    //根据微服务的名字获取Spring容器

    AnnotationConfigApplicationContext context = getContext(name);

    if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,type).length > 0) {

        return context.getBean(type);

    }

    return null;

}

(NamedContextFactory)protected AnnotationConfigApplicationContext getContext(String name) {

        if (!this.contexts.containsKey(name)) {

            synchronized (this.contexts) {

                if (!this.contexts.containsKey(name)) {

                    this.contexts.put(name, createContext(name));

                }

            }

        }

        return this.contexts.get(name);

}

protected AnnotationConfigApplicationContext createContext(String name) {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

        context.register(PropertyPlaceholderAutoConfiguration.class,this.defaultConfigType);

        context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(

        this.propertySourceName,

        Collections.<String, Object> singletonMap(this.propertyName, name)));

        context.refresh();

        return context;

}

8、获取服务Server server = getServer(loadBalancer);

protected Server getServer(String serviceId) {

    return getServer(getLoadBalancer(serviceId));

}

 

protected Server getServer(ILoadBalancer loadBalancer) {

    if (loadBalancer == null) {

        return null;

    }

    return loadBalancer.chooseServer("default"); // TODO: better handling of key

}

 (ZoneAwareLoadBalancer默认)public Server chooseServer(Object key) {

            //因为没有指定zone所以直接采用默认的zone

            if (!ENABLED.get() || getLoadBalancerStats().getAvailableZones().size() <= 1) {

                       return super.chooseServer(key);

            }

}

(ZoneAvoidanceRule)public Server chooseServer(Object key) {

        return rule.choose(key);

}

9、选取完服务之后进行调用  execute(serviceId, ribbonServer, request);

@Override

public <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException {

            Server server = null;

            if(serviceInstance instanceof RibbonServer) {

                server = ((RibbonServer)serviceInstance).getServer();

            }

         RibbonLoadBalancerContext context = this.clientFactory.getLoadBalancerContext(serviceId);

         RibbonStatsRecorder statsRecorder = new RibbonStatsRecorder(context, server);

 

        try {

            T returnVal = request.apply(serviceInstance);

            statsRecorder.recordStats(returnVal);

            return returnVal;

        }

}

 public ClientHttpResponse apply(final ServiceInstance instance)throws Exception {

            HttpRequest serviceRequest = new ServiceRequestWrapper(request, instance, loadBalancer);

            if (transformers != null) {

                 for (LoadBalancerRequestTransformer transformer : transformers) {

                       serviceRequest = transformer.transformRequest(serviceRequest, instance);

                  }

            return execution.execute(serviceRequest, body);

 }

10.一直等到等到把所有的拦截器都执行完成,之后执行请求。

@Override

public ClientHttpResponse execute(HttpRequest request, byte[] body) throws IOException {

            if (this.iterator.hasNext()) {

                ClientHttpRequestInterceptor nextInterceptor = this.iterator.next();

                return nextInterceptor.intercept(request, body, this);

            }else {

                ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), request.getMethod());

                for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {

                    List<String> values = entry.getValue();

                    for (String value : values) {

                        delegate.getHeaders().add(entry.getKey(), value);

                    }

                }

                if (body.length > 0) {

                    StreamUtils.copy(body, delegate.getBody());

                }

                return delegate.execute();

        }

}

11、return delegate.execute();

(SimpleBufferingClientHttpRequest)public final ClientHttpResponse execute() throws IOException {

                assertNotExecuted();

                ClientHttpResponse result = executeInternal(this.headers);

                this.executed = true;

                return result;

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值