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