Spring Cloud Open Feign系列【4】集成OkHttp及连接池配置详解
文章目录Feign 如何发送请求Client 接口Default 类Proxied 类Feign 对其他HTTP 客户端框架的支持支持项HTTP 连接池Feign集成Ok Http1. 添加okhttp 依赖2. 添加配置3. 连接池配置4. 简单测试Feign 如何发送请求在之前文档中,可以了解到,Feign 是集成了其他HTTP 客户端框架进行请求发送。实际发送请求是由Feign 中的Clie
文章目录
Feign 如何发送请求
在之前文档中,可以了解到,Feign 是集成了其他HTTP 客户端框架进行请求发送。
实际发送请求是由Feign 中的Client
接口实现类去处理的,默认使用的是Defalut 类,该类使用的是HttpURLConnection
。
Client 接口
Client 接口只有一个execute 方法,该方法有两个参数:
- Request :请求对象,封装了该请求的方式、参数、返回值类型等数据
- Options :连接超时、读取超时配置项
public interface Client {
Response execute(Request var1, Options var2) throws IOException;
}
该接口在Feign 中有以下几个实现类:
Default 类
Default
是Client 接口的默认实现类,重写了execute 方法。
// 执行请求
public Response execute(Request request, Options options) throws IOException {
// 1. 处理请求
HttpURLConnection connection = this.convertAndSend(request, options);
// 2. 发送请求、处理响应
return this.convertResponse(connection, request);
}
可以看到Default 在发送请求时,实际使用的是HttpURLConnection
(JDK 提供的网络编程包)。
HttpURLConnection convertAndSend(Request request, Options options) throws IOException {
// 创建URL
URL url = new URL(request.url());
// 获取连接
HttpURLConnection connection = this.getConnection(url);
// https 处理
if (connection instanceof HttpsURLConnection) {
HttpsURLConnection sslCon = (HttpsURLConnection)connection;
if (this.sslContextFactory != null) {
sslCon.setSSLSocketFactory(this.sslContextFactory);
}
if (this.hostnameVerifier != null) {
sslCon.setHostnameVerifier(this.hostnameVerifier);
}
}
// 连接配置
connection.setConnectTimeout(options.connectTimeoutMillis());
connection.setReadTimeout(options.readTimeoutMillis());
connection.setAllowUserInteraction(false);
// 省略.....
return connection;
}
}
Proxied 类
Proxied
类继承了Default,有一个 Proxy
属性,提供了代理服务器去访问的方式。
Feign 对其他HTTP 客户端框架的支持
支持项
在Feign
的功能图中,可以看到 Feign 对其他HTTP 客户端框架的支持,比如常用的有Ok Http、Apache Http Client。
HTTP 连接池
在HTTP 通信的过程中,建立连接是一个很复杂的过程,涉及到多个数据包的交换,很耗时间,而且HTTP连接需要3次握手和4次挥手开销都很大。
这时可以采用HTTP连接池
,节约大量的3次握手4次挥手时间,提升吞吐量。
默认的HttpURLConnection
是JDK自带的,并不支持连接池,如果要实现连接池的机制,还需要自己来管理连接对象。
HttpClient
相比传统JDK自带的HttpURLConnection,它封装了访问HTTP的请求头,参数,内容体,响应等等。它不仅使客户端发送HTTP请求变得容易,而且也方便了开发人员测试接口(基于HTTP协议的),既提高了开发的效率,又提高了代码的健壮性。另外高并发大量的请求网络的时候,也是用"连接池"
提升吞吐量。
OkHttp
作为后期之秀,功能和性能上,可能稍优于HttpClient
,但是几乎没多大区别,实际使用时,都是可以的,不过HttpClient
集成起来更方便。
Feign集成Ok Http
1. 添加okhttp 依赖
直接添加okhttp
:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
可以看到当前使用的是3.14.9
版本:
在feign-okhttp-10.12.jar
中,提供了Client 的实现类,可以看到,执行请求时,使用的是OkHttp 中的API。
2. 添加配置
要开启OkHttp ,还需要在YML 中添加开启配置项,默认是关闭的:
feign:
okhttp:
enabled: true
然后重新启动程序,进入Debug 模式,可以看到最终请求是由OkHttp 发送,集成成功。
3. 连接池配置
在配置Feign 的时候,可以看到httpclient
默认提供了配置项,但是OkHttp 并没有默认配置项。
在使用Spring 时,可以通过@Bean
声明这些配置,在实际项目中,应该把这些配置项写在配置类中。
@Configuration
public class OkHttpConfig {
/**
* 忽略证书校验
*
* @return 证书信任管理器
*/
@Bean
public X509TrustManager x509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@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 e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
/**
* 连接池配置
*
* @return 连接池
*/
@Bean
public ConnectionPool pool() {
// 最大连接数、连接存活时间、存活时间单位(分钟)
return new ConnectionPool(200, 5, TimeUnit.MINUTES);
}
/**
* 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 HostnameVerifier hostnameVerifier() {
return (s, sslSession) -> true;
}
}
启动项目,Dubug 到OkHttpClient,可以看到,配置生效,连接池配置成功。
4. 简单测试
最后使用Jemeter 简单测试下,可以看到使用连接池后,吞吐量明显提升。
使用HttpURLConnection:
使用Okhttp + 连接池:
更多推荐
所有评论(0)