Spring中的RestTemplate类源自spring-web,http调用中设置超时时间、设置链接池管理等很是重要,保证了系统的可用性,避免了长时间链接不上或者等待数据返回,拖垮系统。java
现贴出工做上关于RestTemplate的标准配置,设置了超时时间、链接池等,开箱即用。web
package com.pab.bloan.charge.app.common.config; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import org.apache.http.client.config.RequestConfig; import org.apache.http.config.SocketConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.client.RestTemplate; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @Configuration public class RestTemplateConfig { private static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 100; private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 10; private static final int DEFAULT_MAX_TIME_OUT = 3000; @Value("${rest-template.timeout:3000}") private int defaultTimeOut; @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(httpRequestFactory()); List<HttpMessageConverter<?>> converters = new ArrayList<>(); FastJsonHttpMessageConverter jacksonMessageConverter = new FastJsonHttpMessageConverter(); converters.add(jacksonMessageConverter); restTemplate.setMessageConverters(converters); return restTemplate; } @Bean public ClientHttpRequestFactory httpRequestFactory() { HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); RequestConfig requestConfig = RequestConfig.custom() // 链接超时 .setConnectTimeout(defaultTimeOut) // 排队超时 .setConnectionRequestTimeout(defaultTimeOut) // 数据读取超时 .setSocketTimeout(defaultTimeOut) .build(); requestFactory.setConnectTimeout(defaultTimeOut); requestFactory.setReadTimeout(defaultTimeOut); SocketConfig socketConfig = SocketConfig .custom() .setSoKeepAlive(false) .setTcpNoDelay(true) .build(); PoolingHttpClientConnectionManager pm = new PoolingHttpClientConnectionManager(); pm.setDefaultSocketConfig(socketConfig); pm.closeIdleConnections(DEFAULT_MAX_TIME_OUT, TimeUnit.MICROSECONDS); pm.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS); pm.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE); CloseableHttpClient httpClient = HttpClientBuilder.create() .setDefaultRequestConfig(requestConfig) .setConnectionManager(pm) .build(); requestFactory.setHttpClient(httpClient); return requestFactory; } }
使用示例(代码中将相关的请求url、请求参数、响应参数,替换掉便可):spring
/** * 调用渠道查询客户经理名单接口 * @param saleManagerRequest * @return */ private SaleManagerResponse requestQDSaleManagerApi(SaleManagerRequest saleManagerRequest) { // 调用外联额度变动接口 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); ResponseEntity<SaleManagerResponse> responseEntity = restTemplate.postForEntity(accessGatewayService.getAccessGatewayRequestUrl(qdSaleManagerSearchUrl), new HttpEntity<>(saleManagerRequest, headers), SaleManagerResponse.class); if (responseEntity.getStatusCode() == HttpStatus.OK) { SaleManagerResponse saleManagerResponse = responseEntity.getBody(); if (saleManagerResponse != null && Response.SUCCESS.equals(saleManagerResponse.getResponseCode())) { return saleManagerResponse; } else { log.error("request destination error:[requestUrl:{}; request:{}; response:{}]", new Object[]{qdSaleManagerSearchUrl, saleManagerRequest, saleManagerResponse}); throw new BusinessException("调用渠道查询客户经理名单接口异常"); } } else { throw new BusinessException("调用渠道查询客户经理名单接口网络不可达"); } }
标准化代码,用起来美滋滋。apache