RestTemplate 连接池配置
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
RestTemplate的默认连接池是SimpleClientHttpRequestFactory
。
自定义连接池如下所示
配置文件类
/**
* RestTemplate 客户端 Httpclient 的线程池配置
*
* @author fengxuechao
* @version 0.1
* @date 2019/11/12
*/@ConfigurationProperties(prefix="http-pool")@DatapublicclassHttpPoolProperties{/**
* 最大线程数
*/private Integer maxTotal=20;/**
* 默认线程数
*/private Integer defaultMaxPerRoute=10;/**
* 连接上服务器(握手成功)的时间
*/private Integer connectTimeout=1000;/**
* 从连接池中获取连接的超时时间
*/private Integer connectionRequestTimeout=3000;/**
* 服务器返回数据(response)的时间
*/private Integer socketTimeout=5000;/**
* 用于校验线程空闲的时间
*/private Integer validateAfterInactivity=7000;/**
* 开启异步线程池
*/private Boolean async=false;}
连接池配置类
忽略SSL
/**
* @author fengxuechao
* @version 0.1
* @date 2019/12/17
*/@Slf4j@ComponentpublicclassHttpClientHelper{public SSLContextgetSslContext(){// 在调用SSL之前需要重写验证方法,取消检测SSL
X509TrustManager trustManager=newX509TrustManager(){@Overridepublic X509Certificate[]getAcceptedIssuers(){return null;}@OverridepublicvoidcheckClientTrusted(X509Certificate[] xcs, String str){}@OverridepublicvoidcheckServerTrusted(X509Certificate[] xcs, String str){}};
SSLContext ctx= null;try{
ctx= SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
ctx.init(null,newTrustManager[]{trustManager}, null);}catch(NoSuchAlgorithmException| KeyManagementException e){
log.error("创建 SSL 失败", e);}assert ctx!= null;return ctx;}}
配置类
/**
* HttpClient 的配置
*
* @author fengxuechao
* @version 0.1
* @date 2019/11/12
*/@Slf4j@Configuration@ConditionalOnClass({HttpClient.class})@EnableConfigurationProperties(HttpPoolProperties.class)publicclassHttpClientConfig{@Autowiredprivate HttpPoolProperties httpPoolProperties;@Autowiredprivate HttpClientHelper helper;@Bean("httpRequestFactory")@ConditionalOnMissingBeanpublic ClientHttpRequestFactoryhttpRequestFactory(){returnnewHttpComponentsClientHttpRequestFactory(httpClient());}@Bean("httpClient")@ConditionalOnMissingBeanpublic HttpClienthttpClient(){// 在调用SSL之前需要重写验证方法,取消检测SSL
X509TrustManager trustManager=newX509TrustManager(){@Overridepublic X509Certificate[]getAcceptedIssuers(){return null;}@OverridepublicvoidcheckClientTrusted(X509Certificate[] xcs, String str){}@OverridepublicvoidcheckServerTrusted(X509Certificate[] xcs, String str){}};
SSLConnectionSocketFactory socketFactory= null;try{
SSLContext ctx= helper.getSslContext();
ctx.init(null,newTrustManager[]{ trustManager}, null);
socketFactory=newSSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);}catch(KeyManagementException e){
log.error("创建 SSL 失败", e);}assert socketFactory!= null;
Registry<ConnectionSocketFactory> registry= RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", socketFactory).build();
PoolingHttpClientConnectionManager connectionManager=newPoolingHttpClientConnectionManager(registry);
connectionManager.setMaxTotal(httpPoolProperties.getMaxTotal());
connectionManager.setDefaultMaxPerRoute(httpPoolProperties.getDefaultMaxPerRoute());
connectionManager.setValidateAfterInactivity(httpPoolProperties.getValidateAfterInactivity());
RequestConfig requestConfig= RequestConfig.custom()//服务器返回数据(response)的时间,超过抛出read timeout.setSocketTimeout(httpPoolProperties.getSocketTimeout())//连接上服务器(握手成功)的时间,超出抛出connect timeout.setConnectTimeout(httpPoolProperties.getConnectTimeout())//从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool.setConnectionRequestTimeout(httpPoolProperties.getConnectionRequestTimeout()).build();return HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setConnectionManager(connectionManager).build();}}
RestTemplate 配置
/**
* @author fengxuechao
* @version 0.1
* @date 2019/11/12
*/@Configuration@Import({HttpClientConfig.class})publicclassRestTemplateConfiguration{/**
* 普通的 RestTemplate
*
* @return
*/@Bean("restTemplate")@ConditionalOnMissingBean@ConditionalOnBean(value= ClientHttpRequestFactory.class)public RestTemplaterestTemplate(ClientHttpRequestFactory httpRequestFactory){
RestTemplate restTemplate=newRestTemplate(httpRequestFactory);
restTemplate.getMessageConverters().set(1,newStringHttpMessageConverter(StandardCharsets.UTF_8));return restTemplate;}}