当前位置: 首页 > article >正文

Spring Cloud全解析:服务调用之OpenFeign集成OkHttp


文章目录

    • OpenFeign集成OkHttp
      • 添加依赖
      • 配置连接池
      • yml配置


OpenFeign集成OkHttp

OpenFeign本质是HTTP来进行服务调用的,也就是需要集成一个Http客户端。

使用的是Client接口来进行请求的

public interface Client {

 // request是封装的请求方式、参数、返回值类型
  // options 是连接超时、读取超时等的配置项
  Response execute(Request request, Options options) throws IOException;
}

默认是HttpURLConnection方式,也就是jdk中提供的最原始的那个

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();
  }
}

HTTP连接需要进行TCP三次握手,是一个比较耗时的操作,一般我们不直接使用HttpURLConnection,而是使用HttpClient/okHttp等支持连接池的客户端工具,以Feign集成OkHttp为例

添加依赖

        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>

其包内有一个Client的实现类OkHttpClient,

public final class OkHttpClient implements Client {

  @Override
  public feign.Response execute(feign.Request input, feign.Request.Options options)
      throws IOException {
    okhttp3.OkHttpClient requestScoped;
    if (delegate.connectTimeoutMillis() != options.connectTimeoutMillis()
        || delegate.readTimeoutMillis() != options.readTimeoutMillis()) {
      requestScoped = delegate.newBuilder()
          .connectTimeout(options.connectTimeoutMillis(), TimeUnit.MILLISECONDS)
          .readTimeout(options.readTimeoutMillis(), TimeUnit.MILLISECONDS)
          .followRedirects(options.isFollowRedirects())
          .build();
    } else {
      requestScoped = delegate;
    }
    Request request = toOkHttpRequest(input);
    Response response = requestScoped.newCall(request).execute();
    return toFeignResponse(response, input).toBuilder().request(input).build();
  }
}

配置连接池

import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

@Configuration
public class OkHttpConfig {
    /**
     * OkHttp 客户端配置
     *
     * @return OkHttp 客户端配
     */
    @Bean
    public OkHttpClient okHttpClient() {
        return new OkHttpClient.Builder()
                .sslSocketFactory(sslSocketFactory(), x509TrustManager())
                .hostnameVerifier(hostnameVerifier())
                .retryOnConnectionFailure(false)    //是否开启缓存
                .connectionPool(pool())             //连接池
                .connectTimeout(15L, TimeUnit.SECONDS) // 连接超时时间
                .readTimeout(15L, TimeUnit.SECONDS) // 读取超时时间
                .followRedirects(true) // 是否允许重定向
                .build();
    }

    /**
     * 忽略证书校验
     *
     * @return 证书信任管理器
     */
    @Bean
    public X509TrustManager x509TrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };
    }

    /**
     * 信任所有 SSL 证书
     *
     * @return
     */
    @Bean
    public SSLSocketFactory sslSocketFactory() {
        try {
            TrustManager[] trustManagers = new TrustManager[]{x509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustManagers, new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 连接池配置
     *
     * @return 连接池
     */
    @Bean
    public ConnectionPool pool() {
        // 最大连接数、连接存活时间、存活时间单位(分钟)
        return new ConnectionPool(200, 5, TimeUnit.MINUTES);
    }

    /**
     * 信任所有主机名
     *
     * @return 主机名校验
     */
    @Bean
    public HostnameVerifier hostnameVerifier() {
        return (s, sslSession) -> true;
    }
}

yml配置

要开启OkHttp ,还需要在YML 中添加开启配置项,默认是关闭的

feign:
  okhttp:
    enabled: true

至于为什么需要配这个,看一下FeignAutoConfiguration中装配OkHttp的条件

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnMissingClass("com.netflix.loadbalancer.ILoadBalancer")
@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
@ConditionalOnProperty("feign.okhttp.enabled")
protected static class OkHttpFeignConfiguration

参考文献

  • OpenFeign集成OkHttp

http://www.kler.cn/news/327520.html

相关文章:

  • 一次阿里云ECS免费试用实践
  • leetcode-链表篇4
  • MATLAB编写的RSSI在三维空间上的定位程序,锚点数量无限制(可自定义),带中文注释
  • 如何获取钉钉webhook
  • docker容器mysql数据备份 mysql容器无法启动备份数据
  • 【docker学习】Linux系统离线方式安装docker环境方法
  • 【Linux系列】CMA (Contiguous Memory Allocator) 简单介绍
  • IP地址与5G时代的万物互联
  • 享元模式
  • 【MATLAB源码-第178期】基于matlab的8PSK调制解调系统频偏估计及补偿算法仿真,对比补偿前后的星座图误码率。
  • 智慧农业案例 (一)- 自动化机械
  • vue2圆形标记(Marker)添加点击事件不弹出信息窗体(InfoWindow)的BUG解决
  • 05-函数传值VS传引用
  • 2.点位管理|前后端如何交互——帝可得后台管理系统
  • 基础漏洞——SSTI(服务器模板注入)
  • leetcode-134. 加油站-贪心策略
  • 数据结构与算法学习(2)
  • 汽车灯光系统详细介绍
  • 【机器学习】---深入探讨图神经网络(GNN)
  • 【STM32】 TCP/IP通信协议(3)--LwIP网络接口
  • 将 Intersection Observer 与自定义 React Hook 结合使用
  • 基于RPA+BERT的文档辅助“悦读”系统 | OPENAIGC开发者大赛高校组AI创作力奖
  • ruoyi-python 若依python版本部署及新增模块
  • 基于springboot+微信小程序社区超市管理系统(超市3)(源码+sql脚本+视频导入教程+文档)
  • 使用 CMake 构建 C 语言项目
  • 《Zeotero的学习》
  • Linux中安装ffmpeg
  • 随手记:牛回速归
  • Simulink仿真中get_param函数用法
  • 代码随想录算法训练营Day14