SpringCloud客戶端負(fù)載均衡——Ribbon-創(chuàng)新互聯(lián)

  Ribbon——A ribbon is a long, narrow piece of cloth that you use for tying things together or as a decoration.

創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比南召網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式南召網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋南召地區(qū)。費用合理售后完善,十多年實體公司更值得信賴。

  Ribbon是一個工具類框架,不需要獨立部署。

  負(fù)載均衡設(shè)備/負(fù)載均衡軟件模塊都會維護(hù)一個可用的服務(wù)清單,通過心跳檢測來剔除故障節(jié)點,保證清單中都是可用節(jié)點。

  客戶端負(fù)載均衡,由客戶端節(jié)點維護(hù)要訪問的服務(wù)清單,服務(wù)清單來自于注冊中心。

  如前所示,使用客戶端負(fù)載均衡調(diào)用分兩步:

  1. 服務(wù)提供者注冊到服務(wù)中心。

  2. 服務(wù)消費者通過標(biāo)有@LoadBalanced注解的RestTemplate進(jìn)行服務(wù)調(diào)用。

  在service-consumer服務(wù)中,通過調(diào)用RestTemplate的getForEntity方法,GET調(diào)用hello-service的/hello接口。

  RestTemplate

  GET

  RestTemplate有兩類GET實現(xiàn):getForEntity和getForObject。

  getForEntity()有三個重載實現(xiàn),均返回ResponseEntity,

  // url為請求地址,responseType為響應(yīng)體body的類型,uriVariables為url參數(shù)

  // uriVariables配合url中的占位符進(jìn)行動態(tài)傳參,如:

  // entity = getForEntity("http://user-serivce/user?name={1}", String.class, "John");,將John傳給參數(shù)name

  public ResponseEntity getForEntity(String url, Class responseType, Object... uriVariables) throws RestClientException {

  RequestCallback requestCallback = acceptHeaderRequestCallback(responseType); // new AcceptHeaderRequestCallback(responseType)

  ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); // new ResponseEntityResponseExtractor<>(responseType)

  return nonNull(execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables));

  }

  // uriVariables為Map類型,key需要與url中的占位符對應(yīng),如:

  // params.put("myname", "John");

  // entity = getForEntity("http://user-service/user?name={myname}", String.class, params); 將key為myname對應(yīng)的value——John傳給name

  public ResponseEntity getForEntity(String url, Class responseType, Map uriVariables);

  // 使用URI對象代替url和uriVariables

  public ResponseEntity getForEntity(URI url, Class responseType);

  // 使用:

  ResponseEntity entity = restTemplate.getForEntity(url, String.class, "John");

  String body = entity.getBody();

  ResponseEntity entity = restTemplate.getForEntity(url, User.class, "John");

  User body = entity.getBody();

  getForObject()也有三個重載實現(xiàn),傳入execute方法的不是ResponseExtractor,而是HttpMessageConverterExtractor,返回的則是對象類型,三個重載和getForEntity的三個重載關(guān)系類似:

  public T getForObject(String url, Class responseType, Object... uriVariables) throws RestClientException {

  RequestCallback requestCallback = acceptHeaderRequestCallback(responseType); // new AcceptHeaderRequestCallback(responseType)

  HttpMessageConverterExtractor responseExtractor = new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);

  return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);

  }

  public T getForObject(String url, Class responseType, Map uriVariables);

  public T getForObject(URI url, Class responseType);

  // 使用:

  String result = restTemplate.getForObject(url, String.class, "John");

  User user = restTempleate.getForObject(url, User.class, "John");

  // 使用getForObject可以省略從response中獲取body的步驟

  POST

  RestTemplate有三類POST實現(xiàn):postForEntity和postForObject,postForLocation。

  postForEntity()有三個重載實現(xiàn),均返回ResponseEntity,

  // 相較于getForEntity,新增參數(shù)Object request,reqeust如果是HttpEntity對象,RestTemplate將其當(dāng)作完整的http請求對象處理,request中包含了header和body的內(nèi)容。如果request是普通對象,RestTemplate將其轉(zhuǎn)換為HttpEntity來處理,request作為body。

  // if (request instanceof HttpEntity){this.requestEntity = (HttpEntity) request; }

  // else if (requestBody != null) { this.requestEntity = new HttpEntity<>(request); }

  // else { this.requestEntity = HttpEntity.EMPTY; }

  // 使用:

  // User user = new User("didi", 30);

  // entity = postForEntity("http://user-serivce/user", user, String.class, "John");,將John傳給參數(shù)name

  public ResponseEntity postForEntity(String url, Object request, Class responseType, Object... uriVariables) throws RestClientException {

  RequestCallback requestCallback = httpEntityCallback(request, responseType); // new HttpEntityRequestCallback(requestBody, responseType)

  ResponseExtractor> responseExtractor = responseEntityExtractor(responseType); // new ResponseEntityResonseExtracor<>(responseType)

  return nonNull(execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables));

  }

  public ResponseEntity postForEntity(String url, Object request, Class responseType, Map uriVariables);

  public ResponseEntity postForEntity(URI url, Object request, Class responseType);

  postForObject()也有三個重載實現(xiàn),傳入execute方法的不是ResponseExtractor,而是HttpMessageConverterExtractor,返回的則是對象類型,三個重載和postForEntity的三個重載關(guān)系類似:

  public T postForObject(String url, Object request, Class responseType, Object... uriVariables) throws RestClientException {

  RequestCallback requestCallback = httpEntityCallback(request, responseType);

  HttpMessageConverterExtractor responseExtractor = new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);

  return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);

  }

  public T postForObject(String url, Object request, Class responseType, Map uriVariables);

  public T postForObject(URI url, Object request, Class responseType);

  postForLocation()用于發(fā)送post請求,返回新資源的URI,有三個重載實現(xiàn),均返回URI對象,

  public URI postForLocation(String url, Object request, Object... uriVariables) throws RestClientException {

  RequestCallback requestCallback = httpEntityCallback(request); // new HttpEntityRequestCallback(request, null)

  HttpHeaders headers = execute(url, HttpMethod.POST, requestCallback, headersExtractor(), uriVariables); // new HeadersExtractor()

  return (headers != null ? headers.getLocation() : null);

  }

  public URI postForLocation(String url, Object request, Map uriVariables);

  public URI postForLocation(URI url, Object ruquest);

  execute

  RestTemplate中,不同的請求方式,最終會調(diào)用到execute的三個重載實現(xiàn)上來

  // ------------------------------------

  public T execute(String url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor responseExtractor, Object... uriVariables) {

  URI expanded = getUriTemplateHandler().expand(url, uriVariables);

  return doExecute(expanded, method, requestCallback, responseExtractor);

  }

  public T execute(String url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor responseExtractor, Map uriVariables);

  public T execute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor responseExtractor);

  execute()的三個重載實現(xiàn),都會調(diào)用doExecute()方法,去執(zhí)行請求

  protected T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor responseExtractor) throws RestClientException {

  ClientHttpResponse response = null;

  ClientHttpRequest request = createRequest(url, method);

  if (requestCallback != null) { requestCallback.doWithRequest(request); }

  response = request.execute();// 此處執(zhí)行前會被攔截

  handleResponse(url, method, response);

  return (responseExtractor != null ? responseExtractor.extractData(response) : null);

  }

  doExecute()方法接收的參數(shù)中,有RequestCallback和ResponseExtractor。

  RequestCallback

  AcceptHeaderRequestCallback implements RequestCallback // AcceptHeaderRequestCallback用于GET請求

  HttpEntityRequestCallback extends AcceptHeaderRequestCallback // HttpEntityRequestCallback 用于POST、PUT等請求

  ResponseEntity

  // ResponseEntity擴(kuò)展自HttpEntity,增加了http的status(http請求狀態(tài)碼)

  package org.springframework.http;

  public class ResponseEntity extends HttpEntity {

  private final Object status; // status為int或HttpStatus類型

  // getter/setter...

  }

  // HttpEntity表示http的request或response的entity,包含headers(http請求的頭信息)和body(http請求的請求體)

  package org.springframework.http;

  public class HttpEntity {

  private final HttpHeaders headers;

  private final T body;

  // getter/setter...

  }

  @LoadBalanced

  在服務(wù)消費者中,給RestTemplate添加了@LoadBalanced注解,根據(jù)注釋,該注解用于標(biāo)記RestTemplate使用LoadBalancerClient來配置,即客戶端負(fù)載均衡器。

  // Annotation to mark a RestTemplate bean to be configured to use a LoadBalancerClient.

  public @interface LoadBalanced {}

  LoadBalancerClient

  客戶端負(fù)載均衡器,具有如下能力:

  // Represents a client-side load balancer. 即客戶端負(fù)載均衡器

  interface LoadBalancerClient extends ServiceInstanceChooser {

  // 使用serviceId服務(wù)執(zhí)行request請求

  T execute(String serviceId, LoadBalancerRequest request) throws IOException;

  T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request) throws IOException;

  // 將邏輯服務(wù)名http://myservice/path/to/service 替換為host:port的形式

  URI reconstructURI(ServiceInstance instance, URI original);

  }

  // 選擇一個server用來發(fā)送請求的實現(xiàn)接口

  interface ServiceInstanceChooser {

  // 根據(jù)serviceId,從負(fù)載均衡器選擇一個服務(wù)實例ServiceInstance

  ServiceInstance choose(String serviceId);

  }

  LoadBalancerClient有一個實現(xiàn)類RibbonLoadBalancerClient。

  在RestTemplate的doExecute()方法中,調(diào)用request.execute()之前,會被LoadBalancerInterceptor攔截。該攔截器中有一個LoadBalancerClient實例,此外該攔截器在LoadBalancerAutoConfiguration中被創(chuàng)建。而LoadBalancerAutoConfiguration有兩個特殊的注解@ConditionalOnClass(RestTemplate.class)和@ConditionalOnBean(LoadBalancerClient.class),且注釋明確說明LoadBalancerAutoConfiguration為Ribbon的自動化配置類。

  spring-cloud-commons的loadbalancer包中的配置類,以2.1.2為例

  LoadBalancerAutoConfiguration:創(chuàng)建LoadBalancerInterceptor、創(chuàng)建RestTemplateCustomizer(匿名內(nèi)部類)、創(chuàng)建LoadBalancerRequestFactory、創(chuàng)建SmartInitializingSingleton(匿名內(nèi)部類)

  AsyncLoadBalancerAutoConfiguration:針對AsyncRestTemplate做的類似配置

  spring-cloud-netflix-ribbon中的幾個配置類,以2.1.2為例

  RibbonClientConfiguration:創(chuàng)建IClientConfig、創(chuàng)建IRule,創(chuàng)建IPing,創(chuàng)建ServerList,創(chuàng)建ServerListUpdater,創(chuàng)建ILoadBalancer(使用ZoneAwareLoadBalancer實現(xiàn)),創(chuàng)建ServerListFilter、創(chuàng)建RibbonLoadBalancerContext,創(chuàng)建RetryHandler,創(chuàng)建ServerIntrospector

  RibbonAutoConfiguration:創(chuàng)建HasFeatures,創(chuàng)建SpringClientFactory,創(chuàng)建LoadBalancerClient(使用RibbonLoadBalancerClient實現(xiàn)),創(chuàng)建LoadBalancedRetryFactory(使用RibbonLoadBalancedRetryFactory實現(xiàn)),創(chuàng)建PropertiesFactory,創(chuàng)建RibbonApplicationContextInitializer,創(chuàng)建RestTemplateCustomizer(使用匿名內(nèi)部類),創(chuàng)建RibbonClientHttpRequestFactory

  RestCilentRibbonConfiguration:創(chuàng)建RestClient

  LoadBalancerAutoConfiguration

  Ribbon的自動化配置類:

  @Configuration

  @ConditionalOnClass(RestTemplate.class) // 需要RestTemplate類在classpath中

  @ConditionalOnBean(LoadBalancerClient.class) // 需要LoadBalancerClient的實現(xiàn)Bean在BeanFactory中

  @EnableConfigurationProperties(LoadBalancerRetryProperties.class)

  class LoadBalancerAutoConfiguration {

  @LoadBalanced

  @Autowired(required = false)

  // 工程中注冊的RestTemplate的Bean會在此被加載

  private List restTemplates = Collections.emptyList();

  @Autowired(required = false)

  private List transformers = Collections.emptyList();

  // 創(chuàng)建SmartInitializingSingleton的Bean,負(fù)責(zé)用每個Customizer去修飾每個RestTemplate

  @Bean

  public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(

  ObjectProvider> restTemplateCustomizers) {

  return () -> restTemplateCustomizers.ifAvailable(customizers -> {

  for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {

  for (RestTemplateCustomizer customizer : customizers) {

  customizer.customize(restTemplate);

  }

  }

  });

  }

  @Configuration

  @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")

  static class LoadBalancerInterceptorConfig {

  // 創(chuàng)建攔截器Bean,入?yún)榭蛻舳素?fù)載均衡器

  @Bean

  public LoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient, LoadBalancerRequestFactory requestFactory) {

  return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);

  }

  // 創(chuàng)建一個RestTemplateCustomizer的Bean,負(fù)責(zé)將負(fù)載均衡攔截器加到入?yún)estTemplate的攔截器列表中,添加方式為get、add、set

  @Bean

  @ConditionalOnMissingBean

  public RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {

  return restTemplate -> {

  List list = new ArrayList<>(restTemplate.getInterceptors());

  list.add(loadBalancerInterceptor);

  restTemplate.setInterceptors(list);

  }

  }

  }

  }

  LoadBalancerInterceptor

  負(fù)載均衡攔截器,用于在請求最終執(zhí)行前進(jìn)行攔截,在攔截器的intercept()方法中,首先從request中獲取服務(wù)名稱serviceName,然后調(diào)用request工廠的createRequest()方法,創(chuàng)建一個負(fù)載均衡的request——LoadBalancerRequest實例,最后將其連同serviceName一起作為LoadBalancerClient的execute()方法的入?yún)ⅰ?/p>

  class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {

  LoadBalancerClient loadBalancer;

  LoadBalancerRequestFactory requestFactory;

  public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) {

  // 此處調(diào)用request的getURI方法,

  final URI originalUri = request.getURI();

  String serviceName = originalUri.getHost();

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

  }

  }

  LoadBalancerRequestFactory——創(chuàng)建LoadBalancerRequest的工廠

  public LoadBalancerRequest createRequest(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) {

  // 返回LoadBalancerRequest的匿名內(nèi)部類

  return instance -> {

  // 該LoadBalancerRequest的匿名內(nèi)部類實現(xiàn),先創(chuàng)建一個ServiceRequestWrapper的request,然后調(diào)用execution的execute方法執(zhí)行請求

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

  return execution.execute(serviceRequest, body);

  };

  }

  LoadBalancerRequest

  LoadBalancerRequest使用該接口的apply()的方法,為request添加處理動作

  interface LoadBalancerRequest {

  T apply(ServiceInstance instance);

  }

  ServiceRequestWrapper

  ServiceRequestWrapper繼承自HttpRequestWrapper,HttpRequestWrapper對外提供了獲取一個request的method、URI、headers、methodValue等信息的方法。

  ServiceRequestWrapper改寫了默認(rèn)的getURI()方法,使用客戶端負(fù)載均衡器LoadBalancerClient的重構(gòu)URI的方法,將入?yún)equest的URI進(jìn)行重構(gòu),其具體實現(xiàn)在LoadBalancerClient的實現(xiàn)類RibbonLoadBalancerClient中。

  class ServiceRequestWrapper extends HttpRequestWrapper {

  private final ServiceInstance instance;

  private final LoadBalancerClient loadBalancer;

  public ServiceRequestWrapper(HttpRequest request, ServiceInstance instance, LoadBalancerClient loadBalancer) {}

  @Override

  public URI getURI() {

  // 調(diào)用loadBalancer的reconstructURI方法,進(jìn)行URI重構(gòu),改寫成host:port的形式,具體實現(xiàn)在RibbonLoadBalancerClient中

  return this.loadBalancer.reconstructURI(this.instance, getRequest().getURI());

  }

  }

  RibbonLoadBalancerClient

  RibbonLoadBalancerClient實現(xiàn)了LoadBalancerClient和ServiceInstanceChooser中的execute、reconstructURI、choose方法,完成了請求執(zhí)行、URI重構(gòu)和選擇服務(wù)實例的任務(wù),execute

  class RibbonLoadBalancerClient implements LoadBalancerClient {

  SpringClientFactory clientFactory;

  @Override

  public URI reconstructURI(ServiceInstance instance, URI original) {

  String serviceId = instance.getServiceId();

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

  URI uri; Server server;

  if (instance instanceof RibbonServer) {

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

  uri = updateToSecureConnectionIfNeeded(original, ribbonServer);

  } else {

  server = new Server(instance.getScheme(), instance.getHost(), instance.getPort());

  IClientConfig clientConfig = clientFactory.getClientConfig(serviceId);

  ServerIntrospector serverIntrospector = serverIntrospector(serviceId);

  uri = updateToSecureConnectionIfNeeded(original, clientConfig, serverIntrospector, server);

  }

  // 用server中的host、port等替換原始uri

  return context.reconstructURIWithServer(server, uri);

  }

  public ServiceInstance choose(String serviceId, Object hint) {

  // 先調(diào)用getLoadBalancer方法,根據(jù)serviceId,獲取一個ILoadBalancer

  // 然后調(diào)用getServer(ILoadBalancer loadBalancer, Object hint),使用loadBalancer選擇一個Server,hint默認(rèn)為"default"

  Server server = getServer(getLoadBalancer(serviceId), hint);

  if (server == null) { return null; }

  // 用入?yún)erviceId、選擇的Server,構(gòu)造一個RibbonServer

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

  }

  public T execute(String serviceId, LoadBalancerRequest request, Object hint) {

  // 首先選擇一個RibbonServer,該部分流程與choose相同

  Server server = getServer(getLoadBalancer(serviceId), hint);

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

  // 調(diào)用execute的重載實現(xiàn),執(zhí)行請求

  return execute(serviceId, ribbonServer, request);

  }

  public T execute(String serviceId, ServiceInstance serviceIntance, LoadBalancerRequest request) {

  Server server = null;

  if (serviceInstance instanceof RibbonServer) {

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

  }

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

  RibbonStatsRecorder statsRecorder = new RibbonStatsRecorder(context, server);

  try { 無錫做人流手術(shù)多少錢 http://www.ytsg029.com/

  // 調(diào)用apply,向服務(wù)實例發(fā)起請求

  T returnVal = request.apply(serviceInstance);

  statsRecorder.recordStats(returnVal);

  return returnVal;

  } catch (IOException ex) {

  statsRecorder.recordStats(ex); throw ex;

  } catch (Exception ex) {

  statsRecorder.recordStats(ex); throw ex;

  }

  return null;

  }

  // Ribbon 實現(xiàn)了ServiceInstance接口,即服務(wù)實例接口

  public static class RibbonServer implements ServiceInstance {

  private final String serviceId;

  private final Server server;

  private final boolean secure;

  private Map metadata;

  // @Override方法

  }

  }

  ILoadBalancer

  在RibbonLoadBalancerClient的choose()和execute()方法中,都是通過調(diào)用ILoadBalancer的chooseServer()方法,來選擇一個服務(wù)實例Server的,該ILoadBalancer接口是由Ribbon定義的。

  在ILoadBalancer接口中,定義了軟件負(fù)載均衡器的操作:一個服務(wù)實例的集合、標(biāo)記一個服務(wù)停止、選擇服務(wù)

  package com.netflix.loadbalancer;

  interface ILoadBalancer {

  void addServers(List newServers); // 初始化、后續(xù)添加服務(wù)列表

  Server chooseServer(Object key); // 從負(fù)載均衡器選擇一個服務(wù)實例

  void markServerDown(Server server); // 標(biāo)記并通知某個服務(wù)實例已經(jīng)停止

  List getReachableServers(); // up/reachable狀態(tài)的服務(wù)實例,可以提供正常服務(wù)

  List getAllServers(); // 所有已知的服務(wù)實例,reachable/unreachable都包括

  }

  其中的Server,代表一個服務(wù)端節(jié)點,包含了一個服務(wù)的基本信息:host、port、scheme、id、zone、元數(shù)據(jù)等等。

  在RibbonLoadBalancerClient的choose()和execute()方法中,通過getLoadBalancer()方法,來根據(jù)serviceId獲取ILoadBalancer的實例,然后將其包裝成RibbonServer。

  配置類RibbonClientConfiguration創(chuàng)建ILoadBalancer時如果配置文件里有配置,則使用配置的實現(xiàn),否則默認(rèn)使用ZoneAwareLoadBalancer實現(xiàn)。

  ClientHttpRequestExecution

  RibbonLoadBalancerClient的execute()方法中,調(diào)用了入?yún)oadBalancerRequest的apply方法,execute()方法在LoadBlancerInterceptor的intercept方法中調(diào)用,并傳入LoadBalancerRequestFactory.createRequest創(chuàng)建的LoadBalancerRequest實現(xiàn),其實現(xiàn)中最終使用ClientHttpRequestExecution的execute方法執(zhí)行請求。

  總結(jié)

  使用時,注冊一個使用@LoadBalanced注解修飾的RestTemplate,在需要發(fā)起請求的地方調(diào)用RestTemplate的相應(yīng)的請求方法,最終調(diào)用到其doExecute方法。

  @LoadBalanced注解關(guān)聯(lián)了LoadBalancerClient。

  配置類LoadBalancerAutoConfiguration注冊了如下Bean:

  SmartInitializingSingleton:遍歷restTemplates、遍歷customizers,并customizer.customize(restTemplate)

  LoadBalancerRequestFactory:使用LoadBalancerClient構(gòu)造

  LoadBalancerInterceptor:使用LoadBalancerClient和LoadBalancerRequestFactory創(chuàng)建

  RestTemplateCustomizer:使用LoadBalancerInterceptor構(gòu)造一個匿名類,將注冊的LoadBalancerInterceptor添加進(jìn)restTemplate的interceptors列表中

  攔截器LoadBalancerInterceptor的intercept方法從原始請求中獲取URI,然后使用LoadBalancerClient的execute方法執(zhí)行請求,接收兩個參數(shù):serviceName即host和請求工廠創(chuàng)建的request

  請求工廠LoadBalancerRequestFactory的createRequest方法,由原始請求創(chuàng)建一個LoadBalancerRequest的匿名實現(xiàn)

  負(fù)載均衡請求LoadBalancerRequest接口只有apply方法,其匿名實現(xiàn)創(chuàng)建HttpRequest的實現(xiàn)類ServcieRequestWrapper的實例,然后由ClientHttpRequestExecution的execute方法執(zhí)行請求,返回響應(yīng)ClientHttpResponse

  ServiceRequestWrapper重寫了父類HttpRequestWrapper的getURI方法,返回LoadBalancerClient的reconstructURI方法重構(gòu)的URI

  ClientHttpRequestExecution的實現(xiàn)類是InterceptingClientHttpRequest的內(nèi)部類IntercpetingRequestExecution,其execute方法遍歷interceptors,如果有攔截器,就執(zhí)行攔截方法,如果沒有了,就執(zhí)行請求。

  在4中,LoadBalancerClient的execute方法執(zhí)行請求,其實現(xiàn)類是RibbonLoadBalancerClient。execute 先通過serviceId獲取ILoadBalancer,然后調(diào)用ILoadBalancer的chooseServer方法,選擇一個Server,并將之轉(zhuǎn)換成RibbonServer,RibbonServer是ServiceInstance的子類,最后調(diào)用LoadBalancerRequest的apply方法,執(zhí)行請求,返回響應(yīng)。

分享文章:SpringCloud客戶端負(fù)載均衡——Ribbon-創(chuàng)新互聯(lián)
分享地址:http://muchs.cn/article20/cosico.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、虛擬主機(jī)動態(tài)網(wǎng)站、品牌網(wǎng)站制作、App設(shè)計企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作