gpt4 book ai didi

Feign 使用HttpClient和OkHttp方式

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 32 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章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,代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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的源码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
@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

?
1
2
3
4
5
< dependency >
     < groupId >io.github.openfeign</ groupId >
     < artifactId >feign-httpclient</ artifactId >
     < version >9.4.0</ version >
</ dependency >

使用OkHttp

查看FeignAutoConfiguration.HttpClientFeignConfiguration的源码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@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的依赖,代码如下:

?
1
2
3
4
5
< dependency >
     < groupId >io.github.openfeign</ groupId >
     < artifactId >feign-okhttp</ artifactId >
     < version >10.2.0</ version >
</ dependency >

OpenFeign替换为OkHttp

pom中引入feign-okhttp

?
1
2
3
4
< dependency >
     < groupId >io.github.openfeign</ groupId >
     < artifactId >feign-okhttp</ artifactId >
</ dependency >

在application.yml中配置okhttp

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

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

Feign 使用HttpClient和OkHttp方式

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.

原文链接:https://blog.csdn.net/u010277958/article/details/88730889 。

最后此篇关于Feign 使用HttpClient和OkHttp方式的文章就讲到这里了,如果你想了解更多关于Feign 使用HttpClient和OkHttp方式的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com