千家信息网

Feign使用HttpClient和OkHttp方式分别是怎样的

发表于:2025-11-15 作者:千家信息网编辑
千家信息网最后更新 2025年11月15日,这期内容当中小编将会给大家带来有关Feign使用HttpClient和OkHttp方式分别是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。使用HttpClie
千家信息网最后更新 2025年11月15日Feign使用HttpClient和OkHttp方式分别是怎样的

这期内容当中小编将会给大家带来有关Feign使用HttpClient和OkHttp方式分别是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

使用HttpClient和OkHttp

在Feign中,Client是一个非常重要的组件,Feign最终发送Request请求以及接收Response响应都是由Client组件来完成的。Client在Feign源码中是一个接口,在默认情况下,Client的实现类是Client.Default。Client.Default是由HttpURLConnection来实现网络请求的。另外,Client还支持HttpClient和OkHttp来进行网络请求。

首先查看FeignRibbonClient的自动配置类FeignRibbonClientAutoConfiguration,该类在程序启动的时候注入一些Bean,其中注入了一个BeanName为feignClient的Client类型的Bean。在省缺配置BeanName为FeignClient的Bean的情况下,会自动注入Client.Default这个对象,跟踪Client.Default源码,Client.Default使用的网络请求框架是HttpURLConnection,代码如下:

public static class Default implements Client {        private final SSLSocketFactory sslContextFactory;        private final HostnameVerifier hostnameVerifier;         public Default(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier) {            this.sslContextFactory = sslContextFactory;            this.hostnameVerifier = hostnameVerifier;        }         public Response execute(Request request, Options options) throws IOException {            HttpURLConnection connection = this.convertAndSend(request, options);            return this.convertResponse(connection, request);        }                ......//代码省略}

这种情况下,由于缺乏连接池的支持,在达到一定流量的后服务肯定会出问题 。

使用HttpClient

那么如何在Feign中使用HttpClient的框架呢?我们查看FeignAutoConfiguration.HttpClientFeignConfiguration的源码:

@Configuration    @ConditionalOnClass({ApacheHttpClient.class})    @ConditionalOnMissingClass({"com.netflix.loadbalancer.ILoadBalancer"})    @ConditionalOnMissingBean({CloseableHttpClient.class})    @ConditionalOnProperty(        value = {"feign.httpclient.enabled"},        matchIfMissing = true    )    protected static class HttpClientFeignConfiguration {        private final Timer connectionManagerTimer = new Timer("FeignApacheHttpClientConfiguration.connectionManagerTimer", true);        @Autowired(            required = false        )        private RegistryBuilder registryBuilder;        private CloseableHttpClient httpClient;         protected HttpClientFeignConfiguration() {        }         @Bean        @ConditionalOnMissingBean({HttpClientConnectionManager.class})        public HttpClientConnectionManager connectionManager(ApacheHttpClientConnectionManagerFactory connectionManagerFactory, FeignHttpClientProperties httpClientProperties) {            final HttpClientConnectionManager connectionManager = connectionManagerFactory.newConnectionManager(httpClientProperties.isDisableSslValidation(), httpClientProperties.getMaxConnections(), httpClientProperties.getMaxConnectionsPerRoute(), httpClientProperties.getTimeToLive(), httpClientProperties.getTimeToLiveUnit(), this.registryBuilder);            this.connectionManagerTimer.schedule(new TimerTask() {                public void run() {                    connectionManager.closeExpiredConnections();                }            }, 30000L, (long)httpClientProperties.getConnectionTimerRepeat());            return connectionManager;        }         @Bean        public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory, HttpClientConnectionManager httpClientConnectionManager, FeignHttpClientProperties httpClientProperties) {            RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(httpClientProperties.getConnectionTimeout()).setRedirectsEnabled(httpClientProperties.isFollowRedirects()).build();            this.httpClient = httpClientFactory.createBuilder().setConnectionManager(httpClientConnectionManager).setDefaultRequestConfig(defaultRequestConfig).build();            return this.httpClient;        }         @Bean        @ConditionalOnMissingBean({Client.class})        public Client feignClient(HttpClient httpClient) {            return new ApacheHttpClient(httpClient);        }         @PreDestroy        public void destroy() throws Exception {            this.connectionManagerTimer.cancel();            if (this.httpClient != null) {                this.httpClient.close();            }         }    }

从代码@ConditionalOnClass({ApacheHttpClient.class})注解可知,只需要在pom文件上加上HttpClient依赖即可。另外需要在配置文件中配置feign.httpclient.enabled为true,从@ConditionalOnProperty注解可知,这个配置可以不写,因为在默认情况下就为true:

    io.github.openfeign    feign-httpclient    9.4.0

使用OkHttp

查看FeignAutoConfiguration.HttpClientFeignConfiguration的源码:

@Configuration    @ConditionalOnClass({OkHttpClient.class})    @ConditionalOnMissingClass({"com.netflix.loadbalancer.ILoadBalancer"})    @ConditionalOnMissingBean({okhttp3.OkHttpClient.class})    @ConditionalOnProperty({"feign.okhttp.enabled"})    protected static class OkHttpFeignConfiguration {        private okhttp3.OkHttpClient okHttpClient;         protected OkHttpFeignConfiguration() {        }         @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((long)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);        }    }

同理,如果想要在Feign中使用OkHttp作为网络请求框架,则只需要在pom文件中加上feign-okhttp的依赖,代码如下:

    io.github.openfeign    feign-okhttp    10.2.0

OpenFeign替换为OkHttp

pom中引入feign-okhttp

    io.github.openfeign    feign-okhttp

在application.yml中配置okhttp

feign:  httpclient:    connection-timeout: 2000  #单位ms,默认2000    max-connections: 200 #线程池最大连接数  okhttp:    enabled: true

经过上面设置已经可以使用okhttp了,因为在FeignAutoConfiguration中已实现自动装配

如果需要对okhttp做更精细的参数设置,那需要自定义okhttp的实现,可以模仿上图中的实现

上述就是小编为大家分享的Feign使用HttpClient和OkHttp方式分别是怎样的了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

0