iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Feign 使用HttpClient和OkHttp方式
  • 819
分享到

Feign 使用HttpClient和OkHttp方式

2024-04-02 19:04:59 819人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录使用HttpClient和OkHttp使用HttpClient使用OkHttpOpenFeign替换为OkHttppom中引入feign-okhttp在application.y

使用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的实现,可以模仿上图中的实现

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Feign 使用HttpClient和OkHttp方式

本文链接: https://www.lsjlt.com/news/137319.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作