RestTemplate 是srping封装的http客户端,它简化了与http服务的通信方式,统一了RESTful的标准。
实现方式
实现类型 | 连接池 | 超时设置 |
---|---|---|
默认(HttpURLConnection) | N | Y |
Apache HttpComponents | Y | Y |
Netty | N | Y |
OkHttp | Y | Y |
HttpURLConnection参数
设置 | 描述 |
---|---|
conn.setConnectTimeout(1000) | 设置连接超时时间,单位毫秒。连接超时是指TCP连接握手成功的时间,可以参考http握手和连接 |
conn.setReadTimeout(1000) | 设置读取超时时间,单位毫秒。是指从服务器一次读取数据的时间。参考http超时 |
setUseCaches(boolean) | 是否使用缓存 |
setDoOutput(boolean) | 是否输入参数 |
setDoInput(boolean) | 是否读取参数 |
注意:HttpURLConnection 没有数据连接池的功能,每个请求建立一个连接。
RestTemplate 实现超时
- 基于HttpURLConnection实现超时
@Bean
public RestTemplate getRestTemplate(){
//default
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setReadTimeout(15000);//读取超时
requestFactory.setConnectTimeout(5000);//连接超时
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
- 基于Apache 客户端实现超时
@Bean
public RestTemplate getRestTemplate(){
//apache
return new RestTemplate(getHttpCommonFactory());
}
@Bean
public ClientHttpRequestFactory getHttpCommonFactory(){
return new HttpComponentsClientHttpRequestFactory(httpClient());
}
@Bean
public HttpClient httpClient() {
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build();
//连接池设置
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
//#最大连接数
connectionManager.setMaxTotal(200);
//#并发数
connectionManager.setDefaultMaxPerRoute(20);
//connectionManager.setValidateAfterInactivity(httpPoolProperties.getValidateAfterInactivity());
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(15000) //服务器返回数据(response)的时间,超过抛出read timeout
.setConnectTimeout(1000) //连接上服务器(握手成功)的时间,超出抛出connect timeout
//从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
.setConnectionRequestTimeout(30000)
.build();
return HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(connectionManager)
.build();
}
- netty 超时实现
引入netty 依赖:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.36.Final</version>
</dependency>
初始化RestTemplate
@Bean
public RestTemplate getRestTemplate(){
//netty
Netty4ClientHttpRequestFactory nettyFactory = new Netty4ClientHttpRequestFactory();
nettyFactory.setReadTimeout(15000);
nettyFactory.setConnectTimeout(5000);
return new RestTemplate((ClientHttpRequestFactory)nettyFactory);
}
注意:netty 是一个NIO的实现框架,连接数受到操作系统的限制,在处理客户端超时的时候,注意服务端的处理连接数和并发(非netty服务端设置)。
- okhttp 客户端超时
引入okhttp3 客户端依赖
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.1</version>
</dependency>
使用okhttp3初始化RestTemplate
@Bean
public RestTemplate getRestTemplate(){
//okhttp
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(15000,TimeUnit.MILLISECONDS)
.connectTimeout(Duration.ofMillis(5000))
.connectionPool(new ConnectionPool())
.retryOnConnectionFailure(false)
.build();
OkHttp3ClientHttpRequestFactory okhttpFactory=new OkHttp3ClientHttpRequestFactory(client);
return new RestTemplate((ClientHttpRequestFactory)okhttpFactory);
}
这里的连接池是ConnectionPool,maxPool=2147483647。
static {
executor = new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue(), Util.threadFactory(“OkHttp ConnectionPool”, true));
}