package com.ydtech.config.resttemplate; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.concurrent.TimeUnit; import cn.hutool.core.net.SSLContextBuilder; 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.HttpClientConnectionManager; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import java.util.Collections; @Configuration public class RestTemplateConfig { // 连接池最大连接数 private static final int MAX_TOTAL = 6400; // 默认每条路线的最大值 private static final int DEFAULT_MAX_PER_ROUTE = 3200; // 每个主机的并发 private static final int VALIDATE_AFTER_INACTIVITY = 30000; private static final int IDLE_CONNECTIONS = 30; // 返回数据的超时时间 private static final int SOCKET_TIMEOUT = 180 * 1000; // 连接上服务器的超时时间 private static final int CONNECT_TIMEOUT = 3 * 1000; // 从连接池中获取连接的超时时间 private static final int CONNECTION_REQUEST_TIMEOUT = 1000; @Bean("restTemplate") @Primary public RestTemplate restTemplate() throws NoSuchAlgorithmException, KeyManagementException { RestTemplate restTemplate = new RestTemplate(httpRequestFactory()); restTemplate.setErrorHandler(new CustomResponseErrorHandler()); restTemplate.setInterceptors(Collections.singletonList(new RestTemplateRequestInterceptor())); return restTemplate; } @Bean public ClientHttpRequestFactory httpRequestFactory() throws NoSuchAlgorithmException, KeyManagementException { return new HttpComponentsClientHttpRequestFactory(httpClient()); } @Bean public HttpClient httpClient() throws NoSuchAlgorithmException, KeyManagementException { RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(SOCKET_TIMEOUT) //返回数据的超时时间 .setConnectTimeout(CONNECT_TIMEOUT) //连接上服务器的超时时间 .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT) //从连接池中获取连接的超时时间 .build(); return HttpClientBuilder.create() .setDefaultRequestConfig(requestConfig) .setConnectionManager(poolingConnectionManager()) // 设置重试策略和重试次数 .setServiceUnavailableRetryStrategy(new RestTemplateServiceUnavailableRetryStrategy()) .setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) .build(); } /** * 绕过ssl对证书进行验证,无需将证书导出到jdk管理仓库 */ @Bean("restTemplateIgnoreSSL") public RestTemplate restTemplateIgnoreSSL() throws NoSuchAlgorithmException, KeyManagementException { IgnoreSSLRequestFactory requestFactory = new IgnoreSSLRequestFactory(httpClient()); requestFactory.setConnectTimeout(60000); //连接上服务器(握手成功)的时间 requestFactory.setReadTimeout(60000); //返回数据时间 RestTemplate restTemplate = new RestTemplate(requestFactory); return restTemplate; } private HttpClientConnectionManager poolingConnectionManager() throws NoSuchAlgorithmException, KeyManagementException { SSLContextBuilder contextBuilder = new SSLContextBuilder(); SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(contextBuilder.build(), NoopHostnameVerifier.INSTANCE); Registry registry = RegistryBuilder.create() .register("http", new PlainConnectionSocketFactory()) .register("https", socketFactory).build(); // Registry registry = RegistryBuilder.create().register("http", // PlainConnectionSocketFactory.getSocketFactory()).register("https", SSLConnectionSocketFactory.getSocketFactory()).build(); PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(registry); poolingConnectionManager.setMaxTotal(MAX_TOTAL); poolingConnectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE); poolingConnectionManager.setValidateAfterInactivity(VALIDATE_AFTER_INACTIVITY); poolingConnectionManager.closeIdleConnections(IDLE_CONNECTIONS, TimeUnit.SECONDS); poolingConnectionManager.closeExpiredConnections(); return poolingConnectionManager; } }