2025-07-18 16:38:18 +08:00
|
|
|
package com.bjtds.brichat.config;
|
|
|
|
|
|
2025-09-28 17:30:43 +08:00
|
|
|
import org.apache.http.client.config.RequestConfig;
|
|
|
|
|
import org.apache.http.impl.client.CloseableHttpClient;
|
|
|
|
|
import org.apache.http.impl.client.HttpClients;
|
|
|
|
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
2025-07-18 16:38:18 +08:00
|
|
|
import org.springframework.context.annotation.Bean;
|
|
|
|
|
import org.springframework.context.annotation.Configuration;
|
2025-09-28 17:30:43 +08:00
|
|
|
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
2025-07-18 16:38:18 +08:00
|
|
|
import org.springframework.web.client.RestTemplate;
|
2025-09-28 17:30:43 +08:00
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.PreDestroy;
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
2025-07-18 16:38:18 +08:00
|
|
|
|
|
|
|
|
@Configuration
|
|
|
|
|
public class RestTemplateConfig {
|
2025-09-28 17:30:43 +08:00
|
|
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(RestTemplateConfig.class);
|
|
|
|
|
|
|
|
|
|
private PoolingHttpClientConnectionManager connectionManager;
|
|
|
|
|
private CloseableHttpClient httpClient;
|
|
|
|
|
|
|
|
|
|
// RestTemplate连接池配置参数
|
|
|
|
|
@Value("${rest-template.pool.max-total:300}")
|
|
|
|
|
private int maxTotal;
|
|
|
|
|
|
|
|
|
|
@Value("${rest-template.pool.max-per-route:100}")
|
|
|
|
|
private int maxPerRoute;
|
|
|
|
|
|
|
|
|
|
@Value("${rest-template.timeout.connect:15000}")
|
|
|
|
|
private int connectTimeout;
|
|
|
|
|
|
|
|
|
|
@Value("${rest-template.timeout.socket:60000}")
|
|
|
|
|
private int socketTimeout;
|
|
|
|
|
|
|
|
|
|
@Value("${rest-template.timeout.request:10000}")
|
|
|
|
|
private int connectionRequestTimeout;
|
2025-07-18 16:38:18 +08:00
|
|
|
|
|
|
|
|
@Bean
|
|
|
|
|
public RestTemplate restTemplate() {
|
2025-09-28 17:30:43 +08:00
|
|
|
// 创建连接池管理器
|
|
|
|
|
connectionManager = new PoolingHttpClientConnectionManager();
|
|
|
|
|
|
|
|
|
|
// 设置最大连接数
|
|
|
|
|
connectionManager.setMaxTotal(maxTotal);
|
|
|
|
|
|
|
|
|
|
// 设置每个路由的最大连接数
|
|
|
|
|
connectionManager.setDefaultMaxPerRoute(maxPerRoute);
|
|
|
|
|
|
|
|
|
|
// 设置连接验证间隔
|
|
|
|
|
connectionManager.setValidateAfterInactivity(30000);
|
|
|
|
|
|
|
|
|
|
// 设置连接超时、读取超时等配置
|
|
|
|
|
RequestConfig requestConfig = RequestConfig.custom()
|
|
|
|
|
.setConnectTimeout(connectTimeout) // 连接超时
|
|
|
|
|
.setSocketTimeout(socketTimeout) // 读取超时
|
|
|
|
|
.setConnectionRequestTimeout(connectionRequestTimeout) // 从连接池获取连接超时
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
// 创建HttpClient
|
|
|
|
|
httpClient = HttpClients.custom()
|
|
|
|
|
.setConnectionManager(connectionManager)
|
|
|
|
|
.setDefaultRequestConfig(requestConfig)
|
|
|
|
|
.setConnectionManagerShared(false)
|
|
|
|
|
.evictExpiredConnections() // 自动清理过期连接
|
|
|
|
|
.evictIdleConnections(60, TimeUnit.SECONDS) // 清理60秒空闲连接
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
// 创建HttpComponentsClientHttpRequestFactory
|
|
|
|
|
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
|
|
|
|
|
|
|
|
|
// 创建RestTemplate
|
|
|
|
|
RestTemplate restTemplate = new RestTemplate(factory);
|
|
|
|
|
|
|
|
|
|
logger.info("RestTemplate连接池配置完成 - 最大连接数: {}, 每路由最大连接数: {}, 连接超时: {}ms, 读取超时: {}ms",
|
|
|
|
|
maxTotal, maxPerRoute, connectTimeout, socketTimeout);
|
|
|
|
|
|
|
|
|
|
return restTemplate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取RestTemplate连接池状态
|
|
|
|
|
*/
|
|
|
|
|
public String getRestTemplateConnectionPoolStatus() {
|
|
|
|
|
if (connectionManager != null) {
|
|
|
|
|
return String.format("RestTemplate连接池 - 总连接数: %d, 可用: %d, 已使用: %d, 等待: %d",
|
|
|
|
|
connectionManager.getTotalStats().getAvailable() + connectionManager.getTotalStats().getLeased(),
|
|
|
|
|
connectionManager.getTotalStats().getAvailable(),
|
|
|
|
|
connectionManager.getTotalStats().getLeased(),
|
|
|
|
|
connectionManager.getTotalStats().getPending());
|
|
|
|
|
}
|
|
|
|
|
return "RestTemplate连接池未初始化";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用关闭时清理资源
|
|
|
|
|
*/
|
|
|
|
|
@PreDestroy
|
|
|
|
|
public void destroy() {
|
|
|
|
|
try {
|
|
|
|
|
if (httpClient != null) {
|
|
|
|
|
logger.info("正在关闭RestTemplate连接池...");
|
|
|
|
|
httpClient.close();
|
|
|
|
|
logger.info("RestTemplate连接池已关闭");
|
|
|
|
|
}
|
|
|
|
|
if (connectionManager != null) {
|
|
|
|
|
connectionManager.close();
|
|
|
|
|
logger.info("RestTemplate连接管理器已关闭");
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
logger.error("关闭RestTemplate连接池时发生异常", e);
|
|
|
|
|
}
|
2025-07-18 16:38:18 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|