import java.util.concurrent.TimeUnit; import org.apache.http.HeaderElement; import org.apache.http.HeaderElementIterator; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicHeaderElementIterator; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Autowired private RestTemplateProperties restTemplateProperties; @Bean public RestTemplate restTemplate() { return new RestTemplate(httpRequestFactory()); } @Bean public ClientHttpRequestFactory httpRequestFactory() { return new HttpComponentsClientHttpRequestFactory(httpClient()); } // pool监测线程,定期移除过期连接、空闲连接 /* public static class IdleConnectionMonitorThread extends Thread { private final HttpClientConnectionManager connMgr; public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) { super(); this.connMgr = connMgr; } @Override public void run() { try { while (true) { synchronized (this) { Thread.sleep(5000); connMgr.closeExpiredConnections(); connMgr.closeIdleConnections(5, TimeUnit.SECONDS); } } } catch (InterruptedException e) { e.printStackTrace(); } } } */ @Bean public HttpClient httpClient() { // 支持http和https Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", SSLConnectionSocketFactory.getSocketFactory()).build(); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); connectionManager.setMaxTotal(restTemplateProperties.getMaxTotal()); connectionManager.setDefaultMaxPerRoute(restTemplateProperties.getDefaultMaxPerRoute()); connectionManager.setValidateAfterInactivity(restTemplateProperties.getValidateAfterInactivity()); RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(restTemplateProperties.getConnectTimeout()) .setSocketTimeout(restTemplateProperties.getSocketTimeout()) .setConnectionRequestTimeout(restTemplateProperties.getConnectionRequestTimeout()).build(); // keep-alive策略 ConnectionKeepAliveStrategy keepAliveStrategy = new ConnectionKeepAliveStrategy() { @Override public long getKeepAliveDuration(HttpResponse response, HttpContext context) { // 如果服务端response返回了Keep-Alive header HeaderElementIterator it = new BasicHeaderElementIterator( response.headerIterator(HTTP.CONN_KEEP_ALIVE)); while (it.hasNext()) { HeaderElement he = it.nextElement(); String param = he.getName(); String value = he.getValue(); if (value != null && param.equalsIgnoreCase("timeout")) { try { return Long.parseLong(value) * 1000; } catch (NumberFormatException ignore) { } } } // 否则设置客户端默认keep-alive超时时间 return restTemplateProperties.getClientDefaultKeepAliveTime(); } }; /* Thread t = new IdleConnectionMonitorThread(connectionManager); t.setName("httpconnections-pool-evict-thread"); t.start(); */ return HttpClients.custom() .setDefaultRequestConfig(requestConfig) .setConnectionManager(connectionManager) .evictExpiredConnections() //设置后台线程剔除失效连接 .evictIdleConnections(restTemplateProperties.getMaxIdleTime(), TimeUnit.MILLISECONDS) .setKeepAliveStrategy(keepAliveStrategy).build(); } }
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix="resttemplate") public class RestTemplateProperties { private Integer maxTotal; //总连接数 private Integer defaultMaxPerRoute; //单个路由最大连接数 private Integer connectTimeout; // 与远程服务器建立连接的时间 private Integer connectionRequestTimeout; // 从connection manager获取连接的超时时间 private Integer socketTimeout; // 建立连接之后,等待远程服务器返回数据的时间,也就是两个数据包(请求包和响应包)之间不活动的最大时间 private Integer validateAfterInactivity; private Integer clientDefaultKeepAliveTime; //客户端默认keep-alive时间 private Integer maxIdleTime; //连接最大空闲时间 public Integer getMaxTotal() { return maxTotal; } public void setMaxTotal(Integer maxTotal) { this.maxTotal = maxTotal; } public Integer getDefaultMaxPerRoute() { return defaultMaxPerRoute; } public void setDefaultMaxPerRoute(Integer defaultMaxPerRoute) { this.defaultMaxPerRoute = defaultMaxPerRoute; } public Integer getConnectTimeout() { return connectTimeout; } public void setConnectTimeout(Integer connectTimeout) { this.connectTimeout = connectTimeout; } public Integer getConnectionRequestTimeout() { return connectionRequestTimeout; } public void setConnectionRequestTimeout(Integer connectionRequestTimeout) { this.connectionRequestTimeout = connectionRequestTimeout; } public Integer getSocketTimeout() { return socketTimeout; } public void setSocketTimeout(Integer socketTimeout) { this.socketTimeout = socketTimeout; } public Integer getValidateAfterInactivity() { return validateAfterInactivity; } public void setValidateAfterInactivity(Integer validateAfterInactivity) { this.validateAfterInactivity = validateAfterInactivity; } public Integer getClientDefaultKeepAliveTime() { return clientDefaultKeepAliveTime; } public void setClientDefaultKeepAliveTime(Integer clientDefaultKeepAliveTime) { this.clientDefaultKeepAliveTime = clientDefaultKeepAliveTime; } public Integer getMaxIdleTime() { return maxIdleTime; } public void setMaxIdleTime(Integer maxIdleTime) { this.maxIdleTime = maxIdleTime; } }
resttemplate.max-total=2000 resttemplate.default-max-per-route=1000 resttemplate.connect-timeout=5000 resttemplate.connection-request-timeout=1000 resttemplate.socket-timeout=5000 resttemplate.validate-after-inactivity=2000 resttemplate.client-default-keep-alive-time=5000 resttemplate.max-idle-time=5000
参考: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html