【发布时间】:2021-02-06 14:21:02
【问题描述】:
我正在将 PoolingHttpClientConnectionManager 添加到我们的 Spring Boot 服务中,该服务目前正在使用 RestTemplate 和 CloseableHttpClient 来发出请求。该服务正在使用 Apache httpcomponents 4.5。
如果出现临时网络中断会怎样?不良连接是否会从池中丢弃?或者在中断期间池是否充满了不良连接?中断结束后,池是否会自行恢复?还是我需要编写代码来检测它们并将它们从池中移除?
这是我目前的代码:
@Bean
public CloseableHttpClient closeableHttpClient() {
CloseableHttpClient client = HttpClients.custom()
.setDefaultRequestConfig(getDefaultRequestConfig())
.setConnectionManager(poolingHttpClientConnectionManager())
.setKeepAliveStrategy(getConnectionKeepAliveStrategy())
.setRetryHandler(getHttpRequestRetryHandler())
.build();
return client;
}
@Bean
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
Registry<ConnectionSocketFactory> socketFactoryRegistry = getSocketFactoryRegistry();
PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
poolingConnectionManager.setMaxTotal(maxTotalConnections);
poolingConnectionManager.setDefaultMaxPerRoute(maxRouteConnections);
return poolingConnectionManager;
}
@Bean
public Runnable idleConnectionMonitor(PoolingHttpClientConnectionManager pool) {
return new Runnable() {
@Override
@Scheduled(fixedDelay = 20000)
public void run() {
if (pool != null) {
pool.closeExpiredConnections();
pool.closeIdleConnections(idleConnectionCloseTime, TimeUnit.MILLISECONDS);
}
}
};
}
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setThreadNamePrefix("idleMonitor");
scheduler.setPoolSize(idleMonitorPoolSize);
return scheduler;
}
private RequestConfig getDefaultRequestConfig() {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(establishConnectionTimeout)
.setConnectionRequestTimeout(fetchConnectionTimeout)
.setSocketTimeout(socketInactivityTimeout)
.build();
return requestConfig;
}
private Registry<ConnectionSocketFactory> getSocketFactoryRegistry() {
SSLConnectionSocketFactory socketFactory;
socketFactory = new SSLConnectionSocketFactory(getSSLContext(), new String[] { sslProtocol }, null, new DefaultHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
.<ConnectionSocketFactory> create().register("https", socketFactory)
.build();
return socketFactoryRegistry;
}
private SSLContext getSSLContext() {
TrustStrategy acceptingTrustStrategy = null;
try {
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(new FileInputStream(new File(keyStoreFile)), keyStorePwd.toCharArray());
return new SSLContextBuilder()
.loadTrustMaterial(keyStore, acceptingTrustStrategy)
.loadKeyMaterial(keyStore, keyStorePwd.toCharArray())
.build();
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException | UnrecoverableKeyException e) {
throw new RuntimeException(e);
}
}
private ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() {
return (httpResponse, httpContext) -> {
HeaderIterator headerIterator = httpResponse.headerIterator(HTTP.CONN_KEEP_ALIVE);
HeaderElementIterator elementIterator = new BasicHeaderElementIterator(headerIterator);
while (elementIterator.hasNext()) {
HeaderElement element = elementIterator.nextElement();
String param = element.getName();
String value = element.getValue();
if (value != null && param.equalsIgnoreCase("timeout")) {
return Long.parseLong(value) * 1000; // convert to ms
}
}
return defaultKeepAliveTime;
};
}
private DefaultHttpRequestRetryHandler getHttpRequestRetryHandler() {
return new DefaultHttpRequestRetryHandler(httprequestRetryCount, false);
}
【问题讨论】:
标签: httpclient connection-pooling resttemplate apache-httpcomponents