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:
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> <version>9.4.0</version> </dependency>
使用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的依赖,代码如下:
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> <version>10.2.0</version> </dependency>
OpenFeign替换为OkHttp
pom中引入feign-okhttp
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency>
在application.yml中配置okhttp
feign: httpclient: connection-timeout: 2000 #单位ms,默认2000 max-connections: 200 #线程池最大连接数 okhttp: enabled: true
经过上面设置已经可以使用okhttp了,因为在FeignAutoConfiguration中已实现自动装配
如果需要对okhttp做更精细的参数设置,那需要自定义okhttp的实现,可以模仿上图中的实现
以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。
相关文章
基于springcloud异步线程池、高并发请求feign的解决方案
这篇文章主要介绍了基于springcloud异步线程池、高并发请求feign的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-25解决Feign切换client到okhttp无法生效的坑(出现原因说明)
这篇文章主要介绍了解决Feign切换client到okhttp无法生效的坑(出现原因说明),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-25完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题
这篇文章主要介绍了完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-25C#中HttpWebRequest、WebClient、HttpClient的使用详解
这篇文章主要介绍了C#中HttpWebRequest、WebClient、HttpClient的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25如何解决springcloud feign 首次调用100%失败的问题
这篇文章主要介绍了如何解决springcloud feign 首次调用100%失败的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-23- 这篇文章主要介绍了Feign接口方法返回值设置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-08
- 这篇文章主要介绍了使用Feign消费服务时POST/GET请求方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-25
解决SpringCloud Feign传对象参数调用失败的问题
这篇文章主要介绍了解决SpringCloud Feign传对象参数调用失败的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-24- 这篇文章主要介绍了解决Feign获取异常信息的处理方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-27
详解.NET Core 使用HttpClient SSL请求出错的解决办法
这篇文章主要介绍了.NET Core 使用HttpClient SSL请求出错的解决办法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2021-09-22java HttpClient传输json格式的参数实例讲解
这篇文章主要介绍了java HttpClient传输json格式的参数实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-22Spring Cloud中使用Feign,@RequestBody无法继承的解决方案
这篇文章主要介绍了Spring Cloud中使用Feign,@RequestBody无法继承的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-22- HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽,OkHttp是一个高效的HTTP客户端,下面这篇文章主要给大家介绍了关于OkHttp如何用于安卓网络请求,需要的朋友可以参考下...2021-10-18
一篇文章教你如何在SpringCloud项目中使用OpenFeign
这篇文章主要介绍了SpringCloud 使用Open feign 优化详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-08-16解决Spring Cloud Feign 请求时附带请求头的问题
这篇文章主要介绍了解决Spring Cloud Feign 请求时附带请求头的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-19基于springboot的RestTemplate、okhttp和HttpClient对比分析
这篇文章主要介绍了基于springboot的RestTemplate、okhttp和HttpClient对比分析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-10- 这篇文章主要介绍了SpringBoot使用Feign调用其他服务接口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-16
- 这篇文章主要介绍了使用feign服务调用添加Header参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-24
- 这篇文章主要给大家介绍了关于.NET Core中HttpClient的正确打开方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
在ASP.NET Core中应用HttpClient获取数据和内容
这篇文章主要介绍了在ASP.NET Core中集成和使用HttpClient获取数据和内容,帮助大家更好的理解和学习使用ASP.NET Core,感兴趣的朋友可以了解下...2021-09-22