RestTemplate 配置手册

用户头像
zane
关注
发布于: 2020 年 05 月 26 日
RestTemplate 配置手册

前言

在Spring项目中经常会使用RestTemplate进行接口调用。在使用过程中经常因为一些配置的不合理导致生产的服务问题,如并发低,超时问题等。

该文章特意整理了一些RestTemplate的相关配置,方便排查问题。



配置清单

看Spring的源码可以看到RestTemplate底层还是用的org.apache.http包下相关的HttpClient库。

针对RestTemplate的配置主要可以分为:



  • Http链接池池的配置,主要针对链接池的相关配置,影响并发。

  • Socket配置,主要针对Socket进行配置

  • Resquest的配置,主要是单个Http请求的配置,包括读超时时间,建立连接时间等。



ConnPoolControl

针对链接池的配置,查看源码可以看到主要在这个接口中。

package org.apache.http.pool;
/**
* Interface to control runtime properties of a {@link ConnPool} such as
* maximum total number of connections or maximum connections per route
* allowed.
*
* @param <T> the route type that represents the opposite endpoint of a pooled
* connection.
* @since 4.2
*/
public interface ConnPoolControl<T> {
void setMaxTotal(int max);
int getMaxTotal();
void setDefaultMaxPerRoute(int max);
int getDefaultMaxPerRoute();
void setMaxPerRoute(final T route, int max);
int getMaxPerRoute(final T route);
PoolStats getTotalStats();
PoolStats getStats(final T route);
}

配置项



  • 上面提到的路由指的是按主机对MaxTotal进行再分配。比如:MaxtTotal=400,DefaultMaxPerRoute=200,而服务只连接到https://g.cn时,到这个主机的并发最多只有200;而不是400;而我连接到https://baidu.com 和 https://g.cn时,到每个主机的并发最多只有200;即加起来是400(但不能超过400)

  • 而DefaultMaxPerRoute与MaxPerRoute的区别是:前者是所有路由的默认值,后者是可以单独为特定的路由进行配置。



SocketConfig

package org.apache.http.config;
/**
* Socket configuration.
*
* @since 4.3
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE)
public class SocketConfig implements Cloneable {
public static final SocketConfig DEFAULT = new Builder().build();
private final int soTimeout;
private final boolean soReuseAddress;
private final int soLinger;
private final boolean soKeepAlive;
private final boolean tcpNoDelay;
private final int sndBufSize;
private final int rcvBufSize;
private final int backlogSize;
}

配置项



官网



  • 目前修改这块配置的情况比较少,只有有一个soTimeout会进行设置。但是这个值和后面请求的socketTimeout重复了, 一般也是通过设置请求socketTimeout来控制Socket的读超时时间。



RequestConfig

针对请求的配置,查看源码可以看到主要在这个接口中。

package org.apache.http.client.config;
/**
* Immutable class encapsulating request configuration items.
* The default setting for stale connection checking changed
* to false, and the feature was deprecated starting with version 4.4.
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE)
public class RequestConfig implements Cloneable {
public static final RequestConfig DEFAULT = new Builder().build();
private final boolean expectContinueEnabled;
private final HttpHost proxy;
private final InetAddress localAddress;
private final boolean staleConnectionCheckEnabled;
private final String cookieSpec;
private final boolean redirectsEnabled;
private final boolean relativeRedirectsAllowed;
private final boolean circularRedirectsAllowed;
private final int maxRedirects;
private final boolean authenticationEnabled;
private final Collection<String> targetPreferredAuthSchemes;
private final Collection<String> proxyPreferredAuthSchemes;
private final int connectionRequestTimeout;
private final int connectTimeout;
private final int socketTimeout;
private final boolean contentCompressionEnabled;
}

配置项





官网



优化建议

前面介绍的配置项并不是都会用到,常用的配置有如下几个:



  • MaxTotal——最大连接数

  • DefaultMaxPerRoute——每个路由的默认最大连接数

  • connectionRequestTimeout——连接池获取链接超时时间

  • connectTimeout——建立连接的超时时间

  • socketTimeout——Socket的读超时时间



在Spring中的配置方式

@Configuration
public class RestTemplateConfig {
@Bean
public HttpClientConnectionManager poolingConnectionManager() {
PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager();
poolingConnectionManager.setMaxTotal(1000); // 连接池最大连接数
poolingConnectionManager.setDefaultMaxPerRoute(500); // 每个主机的并发
return poolingConnectionManager;
}
@Bean
public HttpClientBuilder httpClientBuilder() {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//设置HTTP连接管理器
httpClientBuilder.setConnectionManager(poolingConnectionManager());
return httpClientBuilder;
}
@Bean("restTemplate")
@LoadBalanced
public RestTemplate restTemplate(){
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setHttpClient(httpClientBuilder().build());
httpRequestFactory.setConnectionRequestTimeout(3000);//获取链接超时时间
httpRequestFactory.setConnectTimeout(3000);//指客户端和服务器建立连接的timeout
httpRequestFactory.setReadTimeout(120000);//读取数据的超时时间
RestTemplate restTemplate=new RestTemplate(httpRequestFactory);
return restTemplate;
}



MaxTotal和DefaultMaxPerRoute

这两个是一组相关配置,影响服务器并发量。

在需要提高并发量时大家经常会调大MaxTotal,而忽略了DefaultMaxPerRoute,这样的结果会导致并发量并不会提高。

所以在提高MaxTotal参数时,需要考虑系统架构的主机数,相应的提高DefaultMaxPerRoute。一般的建议是DefaultMaxPerRoute大概是MaxTotal的一半左右。



超时时间设置

其他三个设置主要是针对超时时间的设置。

connectionRequestTimeout和connectTimeout不建议设置过长,在网络情况差的情况下会导致大量的连接数被占用

socketTimeout需要更加服务的具体情况来设置,设置过长会导致连接被占用,设置过短会导致大数据下载时出现超时。

公共接口服务,socketTimeout不宜设置过长,应优化接口设计,不要一次返回大量数据。

文件服务,存在大量文件下载需求,socketTimeout可以根据网络情况适当设置大一点。



总结

最终的设置的调优还是一个持续的过程,需要在服务发布过程中持续的监控进行调优。根据具体的业务情况进行最优的配置。



发布于: 2020 年 05 月 26 日 阅读数: 44
用户头像

zane

关注

还未添加个人签名 2019.12.09 加入

还未添加个人简介

评论

发布
暂无评论
RestTemplate 配置手册