欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

RestTemplate集成Ribbbon的示例代碼

 更新時(shí)間:2018年08月03日 10:34:39   作者:楊輝  
這篇文章主要介紹了RestTemplate集成Ribbbon的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧

上一篇文章我們分析了ribbon的核心原理,接下來(lái)我們來(lái)看看springcloud是如何集成ribbon的,不同的springcloud的組件(feign,zuul,RestTemplate)集成ribbon有所不同,這篇文章先來(lái)看看RestTemplate。

RestTemplate的類圖如下

  • HttpAccessor主要根據(jù)ClientHttpRequestFactory創(chuàng)建ClientHttpRequest
  • InterceptingHttpAccessor擴(kuò)展了HttpAccessor,創(chuàng)建攔截的InterceptingClientHttpRequest,這里會(huì)設(shè)置攔截器ClientHttpRequestInterceptor,這是集成ribbon的核心,當(dāng)RestTemplate發(fā)起http請(qǐng)求調(diào)用的時(shí)候,會(huì)先經(jīng)過攔截器,然后才真正發(fā)起http請(qǐng)求。

攔截器ClientHttpRequestInterceptor是如何被設(shè)置的呢?在LoadBalancerAutoConfiguration類中,有如下代碼:

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

只要加入注解@LoadBalancedRestTemplate會(huì)被注入,在沒有引入spring retry組件的時(shí)候,加載如下配置:

@Configuration
@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
static class LoadBalancerInterceptorConfig {
  @Bean
  public LoadBalancerInterceptor ribbonInterceptor(
    LoadBalancerClient loadBalancerClient,
    LoadBalancerRequestFactory requestFactory) {
    return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
  }

  @Bean
  @ConditionalOnMissingBean
  public RestTemplateCustomizer restTemplateCustomizer(
    final LoadBalancerInterceptor loadBalancerInterceptor) {
    return new RestTemplateCustomizer() {
      @Override
      public void customize(RestTemplate restTemplate) {
        List<ClientHttpRequestInterceptor> list = new ArrayList<>(
          restTemplate.getInterceptors());
        list.add(loadBalancerInterceptor);
        restTemplate.setInterceptors(list);
      }
    };
  }
}

這樣RestTemplate就被設(shè)置了LoadBalancerInterceptor,下面來(lái)看看整個(gè)調(diào)用過程

整個(gè)過程有點(diǎn)復(fù)雜,核心就是經(jīng)過攔截器LoadBalancerInterceptor,通過RibbonLoadBalancerClient發(fā)起負(fù)載均衡調(diào)用。RibbonLoadBalancerClientI組合了LoadBalancer,所以具備了負(fù)載均衡的能力,也就是我們?cè)谏弦黄恼陆庾x的ribbon原理。

圖中我們沒有畫出真正發(fā)起http請(qǐng)求的過程,其默認(rèn)是由SimpleClientHttpRequestFactory創(chuàng)建,ClientHttpRequestFactory的類圖如下:

從調(diào)用時(shí)序圖上我們看到,開始我們調(diào)用的是InterceptingClientHttpRequestFactory來(lái)獲取InterceptingClientHttpRequest,它們通過組合的方式集成了ClientHttpRequestFactory和攔截器,InterceptingClientHttpRequest發(fā)起調(diào)用的時(shí)候委托了其內(nèi)部類InterceptingRequestExecution去處理,核心邏輯:

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

首先會(huì)先取出攔截器集合的第一個(gè)執(zhí)行,當(dāng)攔截器執(zhí)行完成后,會(huì)回調(diào)回來(lái),執(zhí)行else的代碼,真正發(fā)起http請(qǐng)求,主要有兩種方式實(shí)現(xiàn)ClientHttpRequestFactory接口:

  • 一種是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)創(chuàng)建底層的Http請(qǐng)求連接
  • 一種方式是使用HttpComponentsClientHttpRequestFactory方式,底層使用HttpClient訪問遠(yuǎn)程的Http服務(wù),使用HttpClient可以配置連接池和證書等信息。

 RestTemplate默認(rèn)是使用SimpleClientHttpRequestFactory,內(nèi)部是調(diào)用jdk的HttpConnection,默認(rèn)超時(shí)為-1,可以這樣設(shè)置超時(shí)時(shí)間:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
  SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
  factory.setConnectTimeout(1000 * 2);//連接超時(shí)時(shí)間
  factory.setReadTimeout(1000 * 1);//讀超時(shí)時(shí)間
  return new RestTemplate(factory);
}

使用HttpComponentsClientHttpRequestFactory方式可以使用連接池(推薦) ,還可以設(shè)置重試策略(具體沒有研究過)

如果想開啟重試機(jī)制,我們可以引入spring的retry組件

<dependency>
  <groupId>org.springframework.retry</groupId>
  <artifactId>spring-retry</artifactId>
  <version>版本號(hào)</version>
</dependency>

這樣springcloud-ribbon就會(huì)加重如下配置:

@Configuration
@ConditionalOnClass(RetryTemplate.class)
public static class RetryAutoConfiguration {
  @Bean
  public RetryTemplate retryTemplate() {
    RetryTemplate template = new RetryTemplate();
    template.setThrowLastExceptionOnExhausted(true);
    return template;
  }

  @Bean
  @ConditionalOnMissingBean
  public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory() {
    return new LoadBalancedRetryPolicyFactory.NeverRetryFactory();
  }
}

@Configuration
@ConditionalOnClass(RetryTemplate.class)
public static class RetryInterceptorAutoConfiguration {
  @Bean
  @ConditionalOnMissingBean
  public RetryLoadBalancerInterceptor ribbonInterceptor(
    LoadBalancerClient loadBalancerClient, LoadBalancerRetryProperties properties,
    LoadBalancedRetryPolicyFactory lbRetryPolicyFactory,
    LoadBalancerRequestFactory requestFactory) {
    return new RetryLoadBalancerInterceptor(loadBalancerClient, properties,
                        lbRetryPolicyFactory, requestFactory);
  }

  @Bean
  @ConditionalOnMissingBean
  public RestTemplateCustomizer restTemplateCustomizer(
    final RetryLoadBalancerInterceptor loadBalancerInterceptor) {
    return new RestTemplateCustomizer() {
      @Override
      public void customize(RestTemplate restTemplate) {
        List<ClientHttpRequestInterceptor> list = new ArrayList<>(
          restTemplate.getInterceptors());
        list.add(loadBalancerInterceptor);
        restTemplate.setInterceptors(list);
      }
    };
  }
}
@Bean
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
@ConditionalOnMissingBean
  public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory(SpringClientFactory clientFactory) {
  return new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
}

攔截器替換成RetryLoadBalancerInterceptor了,這里集成了retry組件retryTemplate。重試策略由RetryHandler接口來(lái)配置,默認(rèn)實(shí)現(xiàn)類DefaultLoadBalancerRetryHandler,如下為默認(rèn)的配置參數(shù)

#最大的重試次數(shù)
ribbon.MaxAutoRetries=0
#最大重試server的個(gè)數(shù)
ribbon.MaxAutoRetriesNextServer=1
#是否開啟任何異常都重試(默認(rèn)在get請(qǐng)求下會(huì)重試,其他情況不會(huì)重試,除非設(shè)置為true)
ribbon.OkToRetryOnAllOperations=false
#指定重試的http狀態(tài)碼
ribbon.retryableStatusCodes=500,501

以上是對(duì)全局生效,如果加上xxx.ribbon.MaxAutoRetries=1這樣只會(huì)對(duì)某個(gè)ribbon客戶端生效。MaxAutoRetries和MaxAutoRetriesNextServer是配合使用的,最大重試次數(shù)是針對(duì)每一個(gè)server的,如果設(shè)置MaxAutoRetries=1,MaxAutoRetriesNextServer=1這樣觸發(fā)最大重試次數(shù)就是4次。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 深入探究如何使用Java編寫MapReduce程序

    深入探究如何使用Java編寫MapReduce程序

    MapReduce是一種用于處理大規(guī)模數(shù)據(jù)集的并行編程模型,其特點(diǎn)高效性和可擴(kuò)展性,在本文中,我們將深入了解MapReduce,并使用Java編寫一個(gè)簡(jiǎn)單的MapReduce程序,需要的朋友可以參考下
    2023-05-05
  • Java簡(jiǎn)單實(shí)現(xiàn)猜數(shù)字游戲附C語(yǔ)言版本

    Java簡(jiǎn)單實(shí)現(xiàn)猜數(shù)字游戲附C語(yǔ)言版本

    猜數(shù)字是興起于英國(guó)的益智類小游戲,起源于20世紀(jì)中期,一般由兩個(gè)人或多人玩,也可以由一個(gè)人和電腦玩。游戲規(guī)則為一方出數(shù)字,一方猜,今天我們來(lái)用Java和C語(yǔ)言分別把這個(gè)小游戲?qū)懗鰜?lái)練練手
    2021-11-11
  • JAVA實(shí)現(xiàn)LRU算法的參考示例

    JAVA實(shí)現(xiàn)LRU算法的參考示例

    這篇文章主要介紹了JAVA實(shí)現(xiàn)LRU算法的參考示例,幫助大家根據(jù)需求實(shí)現(xiàn)算法,感興趣的朋友可以了解下
    2020-10-10
  • Java連接PostgreSql數(shù)據(jù)庫(kù)及基本使用方式

    Java連接PostgreSql數(shù)據(jù)庫(kù)及基本使用方式

    這篇文章主要介紹了Java連接PostgreSql數(shù)據(jù)庫(kù)及基本使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • java8列表中通過stream流根據(jù)對(duì)象屬性去重的三種方式

    java8列表中通過stream流根據(jù)對(duì)象屬性去重的三種方式

    這篇文章主要介紹了java8列表中通過stream流根據(jù)對(duì)象屬性去重的三種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringBoot啟動(dòng)時(shí)如何通過啟動(dòng)參數(shù)指定logback的位置

    SpringBoot啟動(dòng)時(shí)如何通過啟動(dòng)參數(shù)指定logback的位置

    這篇文章主要介紹了SpringBoot啟動(dòng)時(shí)如何通過啟動(dòng)參數(shù)指定logback的位置,在spring boot中,使用logback配置的方式常用的有兩種,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • maven 刪除下載失敗的包的方法

    maven 刪除下載失敗的包的方法

    本文介紹了當(dāng)Maven包報(bào)紅時(shí),使用刪除相關(guān)文件的方法來(lái)解決該問題,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • java常用API介紹之包裝類

    java常用API介紹之包裝類

    這篇文章主要介紹了java常用API介紹之包裝類,API,即Application Programming Interface,中文名稱是“應(yīng)用程序接口",這些接口就是"jdk所提供"給我們使用的類,需要的朋友可以參考下
    2023-04-04
  • JVM的類加載過程以及雙親委派模型詳解

    JVM的類加載過程以及雙親委派模型詳解

    這篇文章主要介紹了JVM的類加載過程以及雙親委派模型詳解,類加載器就是根據(jù)指定全限定名稱將 class 文件加載到 JVM 內(nèi)存,然后再轉(zhuǎn)化為 class 對(duì)象。,需要的朋友可以參考下
    2019-06-06
  • Java中String字符串常量池和intern方法源碼分析

    Java中String字符串常量池和intern方法源碼分析

    在之前的文章中,小編給大家介紹了String字符串的不可變性及其實(shí)現(xiàn)原理,其中給大家提到了字符串常量池的概念,那么什么是常量池,String字符串與常量池有什么關(guān)系,本文給大家嘮嘮字符串常量池及String#intern()方法的作用,需要的朋友可以參考下
    2023-05-05

最新評(píng)論