久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx

Ribbon如何在springcloud中使用

Ribbon如何在spring cloud 中使用?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

十余年的徐聞網站建設經驗,針對設計、前端、開發、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。成都營銷網站建設的優勢是能夠根據用戶設備顯示端的尺寸不同,自動調整徐聞建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優雅布局與設計,從而大程度地提升瀏覽體驗。創新互聯從事“徐聞網站設計”,“徐聞網站推廣”以來,每個客戶項目都認真落實執行。

基本使用

這里使用基于zookeeper注冊中心+ribbon的方式實現一個簡單的客戶端負載均衡案例。

服務提供方

首先是一個服務提供方。代碼如下。

application.properties配置文件

spring.application.name=discovery-service
server.port=0
service-B.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
bootstrap.properties配置文件

spring.cloud.zookeeper.connect-string=192.168.0.15:2181
引導程序,提供了一個ribbonService的rest接口服務,注冊程序到zookeeper中。

@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class DiscoverClient {
  public static void main(String[] args) {
    SpringApplication.run(DiscoverClient.class, args);
  }

  @RequestMapping("/ribbonService")
  public String ribbonService(){
    return "hello too ribbon";
  }
}

服務調用方

服務調用方就是進行負載均衡的一方,利用ribbo的RestTemplate進行負載調用服務。

RibbonConfig,配置ribbon的RestTemplate,通過@LoadBalanced注解實現,具體原理稍后分析。

@Configuration
public class RibbonConfig {

  /**
   * 實例化ribbon使用的RestTemplate
   * @return
   */
  @Bean
  @LoadBalanced
  public RestTemplate rebbionRestTemplate(){
    return new RestTemplate();
  }
  
  /**
  * 配置隨機負載策略,需要配置屬性service-B.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
  */
  @Bean
  public IRule ribbonRule() {
    return new RandomRule();
  }
}

引導程序

@SpringBootApplication(scanBasePackages = "garine.learn.ribbon.loadblance")
@EnableDiscoveryClient
@RestController
public class TestRibbonApplocation {
  public static void main(String[] args) {
    SpringApplication.run(TestRibbonApplocation.class, args);
  }

  @Autowired
  @LoadBalanced
  RestTemplate restTemplate;

  @GetMapping("/{applicationName}/ribbonService")
  public String ribbonService(@PathVariable("applicationName") String applicationName){
    return restTemplate.getForObject("http://" + applicationName+"/ribbonService", String.class);
  }
}

配置文件同上,服務名稱修改即可。

測試

啟動兩個discovery-service,由于端口設置為0,所以是隨機端口。

啟動服務調用方

瀏覽器訪問服務調用方的提供的接口,路徑參數需要加上調用的服務名稱,例如http://localhost:8080/discovery-service/ribbonService,然后服務調用方使用ribbon的RestTemplate調用服務提供方的接口。

結果返回:hello too ribbon ,同時服務提供方啟動的兩個服務都可能被調用,取決于怎么配置負載策略。

上面就是一個簡單使用ribbon的例子,結合feign使用基本上是做類似上面所寫的工作,那么ribbon到底是怎么實現的呢?

原理與源碼分析

ribbon實現的關鍵點是為ribbon定制的RestTemplate,ribbon利用了RestTemplate的攔截器機制,在攔截器中實現ribbon的負載均衡。負載均衡的基本實現就是利用applicationName從服務注冊中心獲取可用的服務地址列表,然后通過一定算法負載,決定使用哪一個服務地址來進行http調用。

Ribbon的RestTemplate

RestTemplate中有一個屬性是List<ClientHttpRequestInterceptor> interceptors,如果interceptors里面的攔截器數據不為空,在RestTemplate進行http請求時,這個請求就會被攔截器攔截進行,攔截器實現接口ClientHttpRequestInterceptor,需要實現方法是

ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException;

也就是說攔截器需要完成http請求,并封裝一個標準的response返回。

ribbon中的攔截器

在Ribbon 中也定義了這樣的一個攔截器,并且注入到RestTemplate中,是怎么實現的呢?

在Ribbon實現中,定義了一個LoadBalancerInterceptor,具體的邏輯先不說,ribbon就是通過這個攔截器進行攔截請求,然后實現負載均衡調用。

攔截器定義在org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration.LoadBalancerInterceptorConfig#ribbonInterceptor

@Configuration
@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
static class LoadBalancerInterceptorConfig {
  @Bean
  //定義ribbon的攔截器
  public LoadBalancerInterceptor ribbonInterceptor(
     LoadBalancerClient loadBalancerClient,
     LoadBalancerRequestFactory requestFactory) {
   return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
  }

  @Bean
  @ConditionalOnMissingBean
  //定義注入器,用來將攔截器注入到RestTemplate中,跟上面配套使用
  public RestTemplateCustomizer restTemplateCustomizer(
     final LoadBalancerInterceptor loadBalancerInterceptor) {
   return restTemplate -> {
        List<ClientHttpRequestInterceptor> list = new ArrayList<>(
            restTemplate.getInterceptors());
        list.add(loadBalancerInterceptor);
        restTemplate.setInterceptors(list);
      };
  }
}

ribbon中的攔截器注入到RestTemplate

定義了攔截器,自然需要把攔截器注入到、RestTemplate才能生效,那么ribbon中是如何實現的?上面說了攔截器的定義與攔截器注入器的定義,那么肯定會有個地方使用注入器來注入攔截器的。

在org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration#loadBalancedRestTemplateInitializerDeprecated方法里面,進行注入,代碼如下。

@Configuration
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnBean(LoadBalancerClient.class)
@EnableConfigurationProperties(LoadBalancerRetryProperties.class)
public class LoadBalancerAutoConfiguration {

  @LoadBalanced
  @Autowired(required = false)
  private List<RestTemplate> restTemplates = Collections.emptyList();

  @Bean
  public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(
     final ObjectProvider<List<RestTemplateCustomizer>> restTemplateCustomizers) {
    //遍歷context中的注入器,調用注入方法。
   return () -> restTemplateCustomizers.ifAvailable(customizers -> {
      for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {
        for (RestTemplateCustomizer customizer : customizers) {
          customizer.customize(restTemplate);
        }
      }
    });
  }
  //......
  }

遍歷context中的注入器,調用注入方法,為目標RestTemplate注入攔截器,注入器和攔截器都是我們定義好的。

還有關鍵的一點是:需要注入攔截器的目標restTemplates到底是哪一些?因為RestTemplate實例在context中可能存在多個,不可能所有的都注入攔截器,這里就是@LoadBalanced注解發揮作用的時候了。

LoadBalanced注解

嚴格上來說,這個注解是spring cloud實現的,不是ribbon中的,它的作用是在依賴注入時,只注入實例化時被@LoadBalanced修飾的實例。

例如我們定義Ribbon的RestTemplate的時候是這樣的

@Bean
  @LoadBalanced
  public RestTemplate rebbionRestTemplate(){
    return new RestTemplate();
  }

因此才能為我們定義的RestTemplate注入攔截器。

那么@LoadBalanced是如何實現這個功能的呢?其實都是spring的原生操作,@LoadBalance的源碼如下

/**
 * Annotation to mark a RestTemplate bean to be configured to use a LoadBalancerClient
 * @author Spencer Gibb
 */
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}

很明顯,‘繼承'了注解@Qualifier,我們都知道以前在xml定義bean的時候,就是用Qualifier來指定想要依賴某些特征的實例,這里的注解就是類似的實現,restTemplates通過@Autowired注入,同時被@LoadBalanced修飾,所以只會注入@LoadBalanced修飾的RestTemplate,也就是我們的目標RestTemplate。

攔截器邏輯實現

LoadBalancerInterceptor源碼如下。

public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {

  private LoadBalancerClient loadBalancer;
  private LoadBalancerRequestFactory requestFactory;

  public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) {
    this.loadBalancer = loadBalancer;
    this.requestFactory = requestFactory;
  }

  public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
    // for backwards compatibility
    this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
  }

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

攔截請求執行

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

我們重點看getServer方法,看看是如何選擇服務的

protected Server getServer(ILoadBalancer loadBalancer) {
  if (loadBalancer == null) {
   return null;
  }
  //
  return loadBalancer.chooseServer("default"); // TODO: better handling of key
}

代碼配置隨機loadBlancer,進入下面代碼

public Server chooseServer(Object key) {
  if (counter == null) {
    counter = createCounter();
  }
  counter.increment();
  if (rule == null) {
    return null;
  } else {
    try {
      //使用配置對應負載規則選擇服務
      return rule.choose(key);
    } catch (Exception e) {
      logger.warn("LoadBalancer [{}]: Error choosing server for key {}", name, key, e);
      return null;
    }
  }
}

這里配置的是RandomRule,所以進入RandomRule代碼

public Server choose(ILoadBalancer lb, Object key) {
  if (lb == null) {
    return null;
  }
  Server server = null;

  while (server == null) {
    if (Thread.interrupted()) {
      return null;
    }
    //獲取可用服務列表
    List<Server> upList = lb.getReachableServers();
    List<Server> allList = lb.getAllServers();

    //隨機一個數
    int serverCount = allList.size();
    if (serverCount == 0) {
      /*
       * No servers. End regardless of pass, because subsequent passes
       * only get more restrictive.
       */
      return null;
    }

    int index = rand.nextInt(serverCount);
    server = upList.get(index);

    if (server == null) {
      /*
       * The only time this should happen is if the server list were
       * somehow trimmed. This is a transient condition. Retry after
       * yielding.
       */
      Thread.yield();
      continue;
    }

    if (server.isAlive()) {
      return (server);
    }

    // Shouldn't actually happen.. but must be transient or a bug.
    server = null;
    Thread.yield();
  }
  return server;
}

看完上述內容,你們掌握Ribbon如何在spring cloud 中使用的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注創新互聯行業資訊頻道,感謝各位的閱讀!

文章標題:Ribbon如何在springcloud中使用
網頁網址:http://www.js-pz168.com/article24/pojcce.html

成都網站建設公司_創新互聯,為您提供標簽優化企業網站制作網站營銷網頁設計公司外貿網站建設ChatGPT

廣告

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

成都seo排名網站優化
久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx
国产日韩视频一区二区三区| 日韩激情一二三区| 日韩av中文在线观看| 国产精品一区二区三区网站| 国产精品一区二区三区四区五区| 中文字幕精品—区二区日日骚| 日韩午夜激情免费电影| **网站欧美大片在线观看| 免费观看在线综合| 91网免费观看| 色老汉av一区二区三区| 久久夜色精品国产欧美乱极品| 亚洲一区自拍偷拍| 国产成人一区二区精品非洲| 另类欧美小说| 91麻豆精品国产自产在线观看一区 | 亚洲图片激情小说| 日韩精品色哟哟| 91嫩草国产在线观看| 色综合久久久久综合体桃花网| 久久品道一品道久久精品| 天天综合网天天综合色| 99国产精品一区| 色呦呦日韩精品| 亚洲国产电影在线观看| 精品一区在线看| 久久亚洲综合网| 日韩欧美一卡二卡| 亚洲高清在线精品| 99在线影院| 欧美日本视频在线| 一区二区三区四区在线播放| 成人国产精品免费观看动漫| 一区二区三区四区五区视频| 欧美国产精品一区二区| 激情文学综合插| 欧美专区一二三| 久久久精品国产99久久精品芒果| 日本不卡视频在线| 久久av一区二区| 精品免费国产二区三区| 日精品一区二区三区| 国产乱码一区| 欧美电影免费观看高清完整版在线 | 亚洲天堂av一区| 成人免费电影视频| 色综合久久66| 亚洲人成7777| 99re这里只有精品视频首页| 91官网在线免费观看| 中文字幕亚洲一区二区va在线| 国产亚洲一区字幕| 精品一区二区三区视频| 欧美一区二区三区电影在线观看| 久久女同精品一区二区| 激情小说亚洲一区| 亚洲三区在线| 日韩一区欧美小说| 91蝌蚪porny| 欧美一卡2卡三卡4卡5免费| 日韩电影在线免费观看| 精品国产乱码久久久久久久软件| 精品三级在线观看| 国内精品久久久久影院色| 无遮挡亚洲一区| 亚洲色图制服诱惑| 91麻豆精品在线观看| 日韩一区二区在线免费观看| 美日韩一级片在线观看| 午夜午夜精品一区二区三区文| 国产精品久久久久久久裸模| 99久久精品久久久久久清纯| 欧美福利视频一区| 美女高潮久久久| 在线不卡视频一区二区| 玉足女爽爽91| 久久精品日产第一区二区三区| 久久色中文字幕| 成人教育av在线| 91精品国产综合久久婷婷香蕉| 久久99精品网久久| 色悠悠久久综合| 午夜精品一区二区三区电影天堂| 精品亚洲欧美日韩| 中文字幕欧美国产| 91麻豆swag| 久久久久成人黄色影片| 成人av在线看| 精品国产免费一区二区三区香蕉| 国产福利视频一区二区三区| 欧美久久久久久蜜桃| 精品午夜久久福利影院| 欧洲视频一区二区| 日本成人中文字幕| 一本大道久久精品懂色aⅴ| 午夜精品久久久久久久99水蜜桃| 日韩欧美在线观看强乱免费| 亚洲一区在线视频| 日本一区二区三不卡| 一区二区三区欧美日韩| 久久国产精品久久| 亚洲欧美日韩中文播放 | 91黄色激情网站| 日本aⅴ亚洲精品中文乱码| 色综合色综合色综合色综合色综合 | 欧美人xxxxx| 一区二区三区免费看视频| 欧美一区1区三区3区公司| 亚洲激情第一区| 亚洲v国产v在线观看| 天天射综合影视| 色94色欧美sute亚洲线路一久| 美国毛片一区二区| 欧美日韩一区国产| 国产九色sp调教91| 精品久久人人做人人爱| 91免费视频网址| 国产精品美女久久久久久久久 | 色88888久久久久久影院野外| 日韩视频国产视频| 99久久伊人网影院| 国产午夜精品一区二区三区视频| 成人一区二区在线| 亚洲婷婷国产精品电影人久久| 欧美不卡在线一区二区三区| 一个色在线综合| 色综合天天做天天爱| 久久国产成人午夜av影院| 8x8x8国产精品| 9人人澡人人爽人人精品| 国产日韩精品一区二区三区在线| 国产亚洲精品自在久久| 亚洲主播在线观看| 91久久精品一区二区| 国产一区二区三区在线观看免费视频| 日韩亚洲欧美综合| 91久久精品www人人做人人爽| 中文字幕一区二区三区不卡在线| 欧美日韩精品免费观看视一区二区 | 欧美一区二区三区四区高清| www.66久久| 中文字幕亚洲精品在线观看| 亚洲欧洲一区二区| 韩国午夜理伦三级不卡影院| 精品福利在线导航| 国偷自产av一区二区三区小尤奈| 亚洲在线中文字幕| 欧美色偷偷大香| 99久久久精品| 亚洲精品欧美综合四区| 在线视频一区二区三| 成人伦理片在线| 日韩码欧中文字| 色屁屁一区二区| 春色校园综合激情亚洲| 国产精品久久久一本精品 | 国产一区在线免费观看| 亚洲成人精品影院| 在线不卡中文字幕| 99在线视频首页| 午夜久久久久久久久久一区二区| 欧美二区在线观看| 国产精品久久久久久久久久直播 | 日韩成人午夜精品| 日韩精品一区二区三区老鸭窝 | 99久久精品国产一区二区三区| 亚洲三级免费电影| 欧美在线一二三四区| 91日韩一区二区三区| 一级做a爱片久久| 4438成人网| 精品国产91亚洲一区二区三区www| 视频在线观看国产精品| 日韩免费看的电影| 欧美国产一区二区在线| 国内偷窥港台综合视频在线播放| 视频一区在线播放| 精品视频在线免费看| 91在线精品观看| 亚洲www啪成人一区二区麻豆| 51精品秘密在线观看| 狠狠色综合欧美激情| 久久精品99久久久| 亚洲国产精品二十页| 色偷偷久久人人79超碰人人澡| 亚洲欧美精品午睡沙发| 欧美日韩久久一区二区| 国产一区二区三区av在线| 久久99久久久久久久久久久| 国产午夜精品在线观看| 色爱区综合激月婷婷| 成人免费91在线看| 久久国产三级精品| 国产精品久久网站| 欧美日韩国产中文| 久久久福利视频| 国产精品99久久久久久宅男| 一区二区三区鲁丝不卡| 欧美变态口味重另类| 亚洲一区二区三区免费看|