专栏名称: hryou0922
目录
相关文章推荐
陈忻儿童心理  ·  《从心理解孩子》在线课程2025春季班招生开 ... ·  昨天  
之乎者野记  ·  日子787|越是没人爱的时候,越要好好爱自己 ·  昨天  
51好读  ›  专栏  ›  hryou0922

Spring cloud系列十五 使用线程池优化feign的http请求组件

hryou0922  · 掘金  ·  · 2018-04-12 02:02

正文

1. 概述

在默认情况下 spring cloud feign在进行各个子服务之间的调用时,http组件使用的是jdk的HttpURLConnection,没有使用线程池。本文先从源码分析feign的http组件对象生成的过程,然后通过为feign配置http线程池优化调用效率。

2. 源码分析

我们分析源码spring cloud feign。在spring-cloud-netflix-core/META-INF/spring.factories中可以看到,在spring boot自动配置会初始化FeignRibbonClientAutoConfiguration,这个类会生成Ribbon的使用http组件。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration,\

分析配置类是FeignRibbonClientAutoConfiguration 下面分析此类import的3个类:HttpClientFeignLoadBalancedConfiguration,OkHttpFeignLoadBalancedConfiguration,DefaultFeignLoadBalancedConfiguration

@Import({ HttpClientFeignLoadBalancedConfiguration.class,
    OkHttpFeignLoadBalancedConfiguration.class,
    DefaultFeignLoadBalancedConfiguration.class })
public class FeignRibbonClientAutoConfiguration {
 …
}

HttpClientFeignLoadBalancedConfiguration
为feigin配置appache client的线程池
当引入ApacheHttpClient.class类时,会初始化这个配置类
方法feignClient()中:根据@ConditionalOnMissingBean(Client.class)知道如果有HttpClient 对象,则创建的ApacheHttpClient使用自己定义的HttpClient 。如果没有,则使用默认值。最后生成LoadBalancerFeignClient对象

@Configuration
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
class HttpClientFeignLoadBalancedConfiguration {

    @Autowired(required = false)
    private HttpClient httpClient;

    @Bean
    @ConditionalOnMissingBean(Client.class)
    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
          SpringClientFactory clientFactory) {
        ApacheHttpClient delegate;
        if (this.httpClient != null) {
            delegate = new ApacheHttpClient(this.httpClient);
        } else {
            delegate = new ApacheHttpClient();
        }
        return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
    }
}

OkHttpFeignLoadBalancedConfiguration
为feigin配置OkHttp,类似apache httpclient, 这里略。
DefaultFeignLoadBalancedConfiguration
为feigin配置HttpURLConnection,
方法feignClient():只有以上两个Client没有生产对象时,才在这个方法中使用Client.Default生成LoadBalancerFeignClient

@Configuration
class DefaultFeignLoadBalancedConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
          SpringClientFactory clientFactory) {
        return new LoadBalancerFeignClient(new Client.Default(null, null),
            cachingFactory, clientFactory);
    }
}

查看Client.Default的源码,Default 使用HttpURLConnection 建立连接且每次请求都建立一个新的连接

 public static class Default implements Client {
    @Override
    public Response execute(Request request, Options options) throws IOException {
      HttpURLConnection connection = convertAndSend(request, options);
      return convertResponse(connection).toBuilder().request(request).build();
    }
   ….
}

综上所述,在默认情况下,spring cloud 没有引入httpclient和okhttp的jar包,所有默认使用HttpURLConnection

3. 使用appach httpclient线程池

默认情况下,服务之间调用使用的HttpURLConnection,效率非常低。为了提高效率,可以通过连接池提高效率,本节我们使用appache httpclient做为连接池。配置OkHttpClient连接池,也是类似的方法,这里略。 经过上节的分析,配置线程池方法:引入appache httpclient并启动对应配置,最后还需要生成HttpClient对象。

3.1. pom.xml中引入feign-httpclient.jar

<!-- 增加feign-httpclient -->
 <dependency>
     <groupId>io.github.openfeign</groupId>
     <artifactId>feign-httpclient</artifactId>
  </dependency>

3.2. 配置参数application-hystrix-feign.yml启动httpclient

# feign配置
feign:
  hystrix:
    # 在feign中开启hystrix功能,默认情况下feign不开启hystrix功能
    enabled: true
  ## 配置httpclient线程池
  httpclient:
    enabled: true
  okhttp:
    enabled: false

3.3. 自定义配置类

使用配置类,生成HttpClient 对象。因为使用PoolingHttpClientConnectionManager连接池,我们需要启动定时器,定时回收过期的连接。配置定时回收连接池的原因,见 问题备忘: httpclient连接池异常引发的惨案







请到「今天看啥」查看全文