RestTemplateConfig.java
RestTemplate配置类
@Slf4j
@Configuration
public class RestTemplateConfig {
/**
* 初始化 RestTemplate 配置线程池和SSH证书信任
*/
@Bean
public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = SSLContextBuilder.create().
loadTrustMaterial((chain, authType) -> true).build();
// 创建 SSL 连接工厂
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext);
// 注册连接工厂
Registry<ConnectionSocketFactory> socketFactoryRegistry =
RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslSocketFactory)
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.build();
// 创建连接池管理器
PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager(socketFactoryRegistry);
// 设置最大连接数
connectionManager.setMaxTotal(restTemplateProperties.getMaxTotalConnections());
// 设置每个路由的最大连接数
connectionManager.setDefaultMaxPerRoute(restTemplateProperties.getDefaultMaxPerRoute());
// 创建 HttpClient 实例并设置连接池
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connectionManager)
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
PoolStats totalStats = connectionManager.getTotalStats();
log.info("自定义线程池初始化:maxTotal: {} ,DefaultMaxPerRoute: {} ,totalStats: {}",
connectionManager.getMaxTotal(), connectionManager.getDefaultMaxPerRoute(),
totalStats.toString());
IdleConnectionMonitor thread = new IdleConnectionMonitor(connectionManager);
thread.start();
// 创建 HttpComponentsClientHttpRequestFactory 实例,并设置连接超时和读取超时
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
// 连接超时时间
requestFactory.setConnectTimeout(restTemplateProperties.getConnectTimeout());
// 读取超时时间
requestFactory.setReadTimeout(restTemplateProperties.getReadTimeout());
requestFactory.setConnectionRequestTimeout(restTemplateProperties.getConnectTimeout());
// 创建 RestTemplate 实例并设置 requestFactory
RestTemplate restTemplate = new RestTemplate(requestFactory);
restTemplate.setInterceptors(Collections.singletonList(new RestTemplateLogInterceptor()));
//提供对传出/传入流的缓冲,可以让响应body多次读取(如果不配置,拦截器读取了Response流,再响应数据时会返回body=null)
restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(requestFactory));
return restTemplate;
}
}
RestTemplateProperties.java
线程池参数配置类
@Data
@Configuration
@ConfigurationProperties(prefix = "XXXX")
public class RestTemplateProperties {
/**
* 连接超时时间
*/
private int connectTimeout;
/**
* 读取超时时间
*/
private int readTimeout;
/**
* 设置最大连接数
*/
private int maxTotalConnections;
/**
* 设置每个路由的最大连接数
*/
private int defaultMaxPerRoute;
}
IdleConnectionMonitor.java
线程池使用情况监控
/**
* 连接池使用情况监控
*/
@Slf4j
public class IdleConnectionMonitor extends Thread {
public static final int WAIT_TIME = 5000;
private HttpClientConnectionManager connMgr;
private volatile boolean shutdown;
public IdleConnectionMonitor(PoolingHttpClientConnectionManager connMgr) {
super();
this.connMgr = connMgr;
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(WAIT_TIME);
PoolStats totalStats = ((PoolingHttpClientConnectionManager) connMgr).getTotalStats();
log.info("monitor total pool stat: {}", totalStats);
Set<HttpRoute> routes = ((PoolingHttpClientConnectionManager) connMgr).getRoutes();
for (HttpRoute route : routes) {
PoolStats stats = ((PoolingHttpClientConnectionManager) connMgr).getStats(route);
log.info("monitor route url {}, current pool stat: {}", route.getTargetHost(), stats);
}
}
}
} catch (InterruptedException ex) {
log.error("连接池使用监控 error", ex);
shutdown();
Thread.currentThread().interrupt();
}
}
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}
技术书籍公众号内回复[ pdf ] Get。
面试笔记、springcloud进阶实战PDF,公众号内回复[ 1222 ] Get。