package com.bjtds.brichat.config; 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; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import org.springframework.beans.factory.annotation.Value; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.PreDestroy; import java.util.concurrent.TimeUnit; @Configuration public class RestTemplateConfig { 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; @Bean public RestTemplate restTemplate() { // 创建连接池管理器 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); } } }