最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Feign使用okhttp的填坑之旅

 更新時(shí)間:2021年02月25日 09:53:17   作者:石楠煙斗的霧  
這篇文章主要介紹了基于Feign使用okhttp的填坑之旅,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧

1、由于項(xiàng)目需要遠(yuǎn)程調(diào)用http請(qǐng)求

因此就想到了Feign,因?yàn)檎娴姆浅5姆奖?,只需要定義一個(gè)接口就行。

但是feign默認(rèn)使用的JDK的URLHttpConnection,沒有連接池效率不好,從Feign的自動(dòng)配置類FeignAutoConfiguration中可以看到Feign除了默認(rèn)的http客戶端還支持okhttp和ApacheHttpClient,我這里選擇了okhttp,它是有連接池的。

2、看看網(wǎng)絡(luò)上大部分博客中是怎么使用okhttp的

1)、引入feign和okhttp的maven坐標(biāo)

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
 
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
 
 <dependency>
   <groupId>io.github.openfeign</groupId>
   <artifactId>feign-okhttp</artifactId>
 </dependency>

2)、在配置文件中禁用默認(rèn)的URLHttpConnection,啟動(dòng)okhttp

feign.httpclient.enabled=false
feign.okhttp.enabled=true

3)、其實(shí)這個(gè)時(shí)候就可以使用okhttp了

但網(wǎng)絡(luò)上大部分博客還寫了一個(gè)自定義配置類,在其中實(shí)例化了一個(gè)okhttp3.OkHttpClient,就是這么一個(gè)配置類導(dǎo)致了大坑啊,有了它之后okhttp根本不會(huì)生效,不信咱們就是來(lái)試一下

@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class OkHttpConfig { 
  @Bean
  public okhttp3.OkHttpClient okHttpClient(){
    return new okhttp3.OkHttpClient.Builder()
        //設(shè)置連接超時(shí)
        .connectTimeout(10 , TimeUnit.SECONDS)
        //設(shè)置讀超時(shí)
        .readTimeout(10 , TimeUnit.SECONDS)
        //設(shè)置寫超時(shí)
        .writeTimeout(10 , TimeUnit.SECONDS)
        //是否自動(dòng)重連
        .retryOnConnectionFailure(true)
        .connectionPool(new ConnectionPool(10 , 5L, TimeUnit.MINUTES))
        .build();
  }
}

上面這個(gè)配置類其實(shí)就是配置了一下okhttp的基本參數(shù)和連接池的基本參數(shù)

此時(shí)我們可以在配置文件中開始日志打印,看一下那些自動(dòng)配置沒有生效

debug=true

啟動(dòng)我們的項(xiàng)目可以在控制臺(tái)搜索到如下日志輸出

FeignAutoConfiguration.OkHttpFeignConfiguration:
   Did not match:
     - @ConditionalOnBean (types: okhttp3.OkHttpClient; SearchStrategy: all) found beans of type 'okhttp3.OkHttpClient' okHttpClient (OnBeanCondition)
   Matched:
     - @ConditionalOnClass found required class 'feign.okhttp.OkHttpClient'; @ConditionalOnMissingClass did not find unwanted class 'com.netflix.loadbalancer.ILoadBalancer' (OnClassCondition)
     - @ConditionalOnProperty (feign.okhttp.enabled) matched (OnPropertyCondition)

從日志中可以清楚的看到FeignAutoConfiguration.OkHttpFeignConfiguration沒有匹配成功(Did not match),原因也很簡(jiǎn)單是因?yàn)槿萜髦幸呀?jīng)存在了okhttp3.OkHttpClient對(duì)象,我們?nèi)タ纯催@個(gè)配置類的源碼,其中類上標(biāo)注了@ConditionalOnMissingBean(okhttp3.OkHttpClient.class),意思上當(dāng)容器中不存在okhttp3.OkHttpClient對(duì)象時(shí)才生效,然后我們卻在自定義的配置類中畫蛇添足的實(shí)例化了一個(gè)該對(duì)象到容器中。

@Configuration(proxyBeanMethods = false)
 @ConditionalOnClass(OkHttpClient.class)
 @ConditionalOnMissingClass("com.netflix.loadbalancer.ILoadBalancer")
 @ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
 @ConditionalOnProperty("feign.okhttp.enabled")
 protected static class OkHttpFeignConfiguration { 
 private okhttp3.OkHttpClient okHttpClient; 
 @Bean
 @ConditionalOnMissingBean(ConnectionPool.class)
 public ConnectionPool httpClientConnectionPool(
  FeignHttpClientProperties httpClientProperties,
  OkHttpClientConnectionPoolFactory connectionPoolFactory) {
  Integer maxTotalConnections = httpClientProperties.getMaxConnections();
  Long timeToLive = httpClientProperties.getTimeToLive();
  TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
  return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
 }
 
 @Bean
 public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory,
  ConnectionPool connectionPool,
  FeignHttpClientProperties httpClientProperties) {
  Boolean followRedirects = httpClientProperties.isFollowRedirects();
  Integer connectTimeout = httpClientProperties.getConnectionTimeout();
  Boolean disableSslValidation = httpClientProperties.isDisableSslValidation();
  this.okHttpClient = httpClientFactory.createBuilder(disableSslValidation)
   .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
   .followRedirects(followRedirects).connectionPool(connectionPool)
   .build();
  return this.okHttpClient;
 }
 
 @PreDestroy
 public void destroy() {
  if (this.okHttpClient != null) {
  this.okHttpClient.dispatcher().executorService().shutdown();
  this.okHttpClient.connectionPool().evictAll();
  }
 }
 
 @Bean
 @ConditionalOnMissingBean(Client.class)
 public Client feignClient(okhttp3.OkHttpClient client) {
  return new OkHttpClient(client);
 } 
 }

4)、該如何處理才能使okhttp生效

其中我們的自定義配置類中并沒有做什么特別復(fù)雜的事情,僅僅是給okhttp3.OkHttpClient和它的連接池對(duì)象設(shè)置了幾個(gè)參數(shù)罷了,看看上面OkHttpFeignConfiguration類中實(shí)例化的幾個(gè)類對(duì)象,其中就包含了okhttp3.OkHttpClient和ConnectionPool,從代碼中不難看出它們的參數(shù)值都是從FeignHttpClientProperties獲取的,因此我們只需要在配置文件中配上feign.httpclient開頭的相關(guān)配置就可以了生效了。

如果我們的目的不僅僅是簡(jiǎn)單的修改幾個(gè)參數(shù)值,比如需要在okhttp中添加攔截器Interceptor,這也非常簡(jiǎn)單,只需要寫一個(gè)Interceptor的實(shí)現(xiàn)類,然后將OkHttpFeignConfiguration的內(nèi)容完全復(fù)制一份到我們自定義的配置類中,并設(shè)置okhttp3.OkHttpClient的攔截器即可。

import okhttp3.Interceptor;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 
import java.io.IOException; 
public class MyOkhttpInterceptor implements Interceptor { 
  Logger logger = LoggerFactory.getLogger(MyOkhttpInterceptor.class); 
  @Override
  public Response intercept(Chain chain) throws IOException {
    logger.info("okhttp method:{}",chain.request().method());
    logger.info("okhttp request:{}",chain.request().body());
    return chain.proceed(chain.request());
  }
}

將自定義配置類中原有的內(nèi)容去掉,復(fù)制一份OkHttpFeignConfiguration的代碼做簡(jiǎn)單的修改,設(shè)置攔截器的代碼如下

  @Bean
  public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory,
                    ConnectionPool connectionPool,
                    FeignHttpClientProperties httpClientProperties) {
    Boolean followRedirects = httpClientProperties.isFollowRedirects();
    Integer connectTimeout = httpClientProperties.getConnectionTimeout();
    Boolean disableSslValidation = httpClientProperties.isDisableSslValidation();
    this.okHttpClient = httpClientFactory.createBuilder(disableSslValidation)
        .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
        .followRedirects(followRedirects).connectionPool(connectionPool)
          //這里設(shè)置我們自定義的攔截器
        .addInterceptor(new MyOkhttpInterceptor())
        .build();
    return this.okHttpClient;
  }

3、最后上兩張圖,F(xiàn)eign的動(dòng)態(tài)代理使用和處理流程

補(bǔ)充:spring cloud feign sentinel okhttp3 gzip 壓縮問題

引入pom okhttp 配置,okhttp使用連接池技術(shù),相對(duì)feign httpUrlConnection 每次請(qǐng)求,創(chuàng)建一個(gè)連接,效率更高

    <dependency>
      <groupId>io.github.openfeign</groupId>
      <artifactId>feign-okhttp</artifactId>
    </dependency>

okhttp 開始?jí)嚎s條件

增加攔截器動(dòng)態(tài)刪除Accept-Encoding 參數(shù),使okhttp壓縮生效

@Slf4j
public class HttpOkInterceptor implements Interceptor {
  @Override
  public Response intercept(Chain chain) throws IOException { 
    Request originRequest = chain.request();
    Response response = null;
    if (StringUtils.isNotEmpty(originRequest.header("Accept-Encoding"))) {
      Request request = originRequest.newBuilder().removeHeader("Accept-Encoding").build();
 
      long doTime = System.nanoTime();
      response = chain.proceed(request);
      long currentTime = System.nanoTime();
      if(response != null) {
        ResponseBody responseBody = response.peekBody(1024 * 1024);
        LogUtil.info(log, String.format("接收響應(yīng): [%s] %n返回json:【%s】 %.1fms%n%s",
            response.request().url(),
            responseBody.string(),
            (currentTime - doTime) / 1e6d,
            response.headers()));
      }else {
        String encodedPath = originRequest.url().encodedPath();
        LogUtil.info(log, String.format("接收響應(yīng): [%s] %n %.1fms%n",
            encodedPath,
            (currentTime - doTime) / 1e6d));
      }
    } 
    return response;
	} 
}

feign 配置

feign:
 sentinel:
  # 開啟Sentinel對(duì)Feign的支持
  enabled: true
 httpclient:
  enabled: false
 okhttp:
  enabled: true

feign 配置類

@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignOkHttpConfig { 
  @Bean
  public okhttp3.OkHttpClient okHttpClient(){
    return new okhttp3.OkHttpClient.Builder()
        //設(shè)置連接超時(shí)
        .connectTimeout(10, TimeUnit.SECONDS)
        //設(shè)置讀超時(shí)
        .readTimeout(10, TimeUnit.SECONDS)
        //設(shè)置寫超時(shí)
        .writeTimeout(10, TimeUnit.SECONDS)
        //是否自動(dòng)重連
        .retryOnConnectionFailure(true)
        .connectionPool(new ConnectionPool(10, 5L, TimeUnit.MINUTES))
        .build(); 
  } 
}

案例:feign client

@FeignClient(name = "服務(wù)名稱",fallbackFactory = FeignFallBack.class ,url = "調(diào)試地址", configuration =FeignConfiguration.class)
public interface FeignService { 
  @RequestMapping(value = "/test/updateXx", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  public ResponseEntity<byte[]> updateXx(@RequestBody XxVo xXVo);  
}

不知為啥 sentinel feign默認(rèn)http,對(duì)壓縮支持不好,使用okhttp 代替實(shí)現(xiàn)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • JavaMail入門教程之解析郵件(5)

    JavaMail入門教程之解析郵件(5)

    這篇文章主要為大家詳細(xì)介紹了JavaMail入門教程之解析郵件的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • java代碼實(shí)現(xiàn)編譯源文件

    java代碼實(shí)現(xiàn)編譯源文件

    這篇文章主要為大家詳細(xì)介紹了Java通過?JavaCompiler?實(shí)現(xiàn)編譯源文件的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2025-01-01
  • SpringBoot2整合Redis實(shí)現(xiàn)讀寫操作

    SpringBoot2整合Redis實(shí)現(xiàn)讀寫操作

    Redis,對(duì)于大家來(lái)說(shuō)應(yīng)該不陌生,是經(jīng)常使用的開發(fā)技術(shù)之一。本文將結(jié)合實(shí)例代碼,介紹SpringBoot2整合Redis實(shí)現(xiàn)讀寫操作,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java經(jīng)典面試題最全匯總208道(六)

    Java經(jīng)典面試題最全匯總208道(六)

    這篇文章主要介紹了Java經(jīng)典面試題最全匯總208道(六),本文章內(nèi)容詳細(xì),該模塊分為了六個(gè)部分,本次為第六部分,需要的朋友可以參考下
    2023-01-01
  • Spring MVC中使用Google kaptcha驗(yàn)證碼的方法詳解

    Spring MVC中使用Google kaptcha驗(yàn)證碼的方法詳解

    kaptcha 是一個(gè)非常實(shí)用的驗(yàn)證碼生成工具。有了它,你可以生成各種樣式的驗(yàn)證碼,因?yàn)樗强膳渲玫?,下面這篇文章主要給大家介紹了關(guān)于Spring MVC中使用Google kaptcha驗(yàn)證碼的方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-10-10
  • Java創(chuàng)建與結(jié)束線程代碼示例

    Java創(chuàng)建與結(jié)束線程代碼示例

    這篇文章主要介紹了Java創(chuàng)建與結(jié)束線程代碼示例,小編覺得挺不錯(cuò)的,這里分享給大家,供需要的朋友參考。
    2017-10-10
  • Java并發(fā)Timer源碼分析

    Java并發(fā)Timer源碼分析

    這篇文章講述了java并發(fā)編程的相關(guān)知識(shí)點(diǎn),并通過Timer源碼分析更深入的講解了java并發(fā)編程。
    2018-07-07
  • Java中對(duì)集合的元素排序操作方法

    Java中對(duì)集合的元素排序操作方法

    本文介紹了Java中對(duì)集合元素進(jìn)行排序的幾種常見方法,包括使用Collections.sort()、List.sort()、StreamAPI以及對(duì)Map的鍵或值進(jìn)行排序,每種方法都有其適用的場(chǎng)景和使用方式,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • java8 LocalDate LocalDateTime等時(shí)間類用法實(shí)例分析

    java8 LocalDate LocalDateTime等時(shí)間類用法實(shí)例分析

    這篇文章主要介紹了java8 LocalDate LocalDateTime等時(shí)間類用法,結(jié)合具體實(shí)例形式分析了LocalDate、LocalTime、LocalDateTime等日期時(shí)間相關(guān)類的功能與具體使用技巧,需要的朋友可以參考下
    2017-04-04
  • java實(shí)現(xiàn)在pdf模板的指定位置插入圖片

    java實(shí)現(xiàn)在pdf模板的指定位置插入圖片

    這篇文章主要為大家詳細(xì)介紹了java如何實(shí)現(xiàn)在pdf模板的指定位置插入圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10

最新評(píng)論

桓台县| 苍山县| 潮安县| 永清县| 高唐县| 兴宁市| 新和县| 井陉县| 阿图什市| 布拖县| 昂仁县| 饶阳县| 阿坝| 凤山市| 吉木乃县| 乌兰县| 信阳市| 监利县| 连江县| 弋阳县| 永嘉县| 荃湾区| 聂拉木县| 台东市| 海丰县| 宁武县| 中江县| 任丘市| 涟源市| 阳高县| 防城港市| 蛟河市| 扶绥县| 神池县| 南漳县| 安西县| 广饶县| 黄龙县| 长岭县| 宁德市| 荣成市|