package com.michaels.configuration; import lombok.extern.slf4j.Slf4j; import org.apache.http.client.HttpClient; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.routing.HttpRoute; 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.conn.ssl.SSLContextBuilder; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.pool.PoolStats; import org.springframework.boot.web.client.RestTemplateBuilder; 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 javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.time.Duration; import java.util.Iterator; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @Slf4j @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) { RestTemplate restTemplate = new RestTemplate(); restTemplate.setRequestFactory(clientHttpRequestFactory()); return restTemplateBuilder .setConnectTimeout(Duration.ofSeconds(15)) .setReadTimeout(Duration.ofSeconds(15)) .build(); } @Bean public RestTemplate longTimeoutRestTemplate(RestTemplateBuilder restTemplateBuilder) { return restTemplateBuilder .setConnectTimeout(Duration.ofSeconds(60)) .setReadTimeout(Duration.ofSeconds(60)) .build(); } public HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() { try { HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { return true; } }).build(); httpClientBuilder.setSSLContext(sslContext); HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,hostnameVerifier); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslConnectionSocketFactory).build();// 注册http和https请求 // 开始设置连接池 PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); poolingHttpClientConnectionManager.setMaxTotal(2000); // 最大连接数2700 poolingHttpClientConnectionManager.closeExpiredConnections(); poolingHttpClientConnectionManager.setDefaultMaxPerRoute(1000); // 同路由并发数100 httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager); httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)); // 重试次数 HttpClient httpClient = httpClientBuilder.build(); HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); // httpClient连接配置 clientHttpRequestFactory.setConnectTimeout(10000); // 连接超时 clientHttpRequestFactory.setReadTimeout(6000); // 数据读取超时时间 clientHttpRequestFactory.setConnectionRequestTimeout(20000); // 连接不够用的等待时间 printLeased(poolingHttpClientConnectionManager);//打印http阻塞数量 return clientHttpRequestFactory; } catch (Exception e) { log.error("初始化HTTP连接池出错"+e.toString()); } return null; } private void printLeased(PoolingHttpClientConnectionManager manager){ ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1); scheduledThreadPool.scheduleAtFixedRate(new Runnable() { @Override public void run() { Set<HttpRoute> routes = manager.getRoutes(); Iterator<HttpRoute> iterator = routes.iterator(); while (iterator.hasNext()){ HttpRoute next = iterator.next(); if(next!=null){ PoolStats stats = manager.getStats(next); log.error(next.toString()+"---最大并发数---"+stats.getMax()+"=剩余请求数---------"+stats.getLeased()+"------"+stats.getPending()); } } } },1,1, TimeUnit.SECONDS); } }
SpringBoot 配置
http: pool: connectionRequestTimeout: 3000 connectTimeout: 6000 socketTimeout: 10000 validateAfterInactivity: 2000 maxTotal: 300 maxPerRoute: 100 idleKeepDuration: 20000 evictIdleDuration: 2000