這篇文章主要介紹“java實用型高并發下RestTemplate的正確使用方法是什么”,在日常操作中,相信很多人在java實用型高并發下RestTemplate的正確使用方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java實用型高并發下RestTemplate的正確使用方法是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
如果java項目里有調用第三方的http接口,我們可以使用RestTemplate去遠程訪問。也支持配置連接超時和響應超時,還可以配置各種長連接策略,也可以支持長連接預熱,在高并發下,合理的配置使用能夠有效提高第三方接口響應時間。
RestTemplate是Spring提供的用于訪問Rest服務的客戶端,RestTemplate提供了多種便捷訪問遠程Http服務的方法,能夠大大提高客戶端的編寫效率。
以下代碼配置比較簡單,只設置了連接超時時間和響應超時時間
/**
* restTemplate配置
*
* @author Songsong
* @date 2020-08-17 15:09
*/
@Configuration
public class RestTemplateConfiguration {
@Bean(name = "restTemplate")
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
//設置連接超時時間1s
factory.setConnectTimeout(1000);
//設置讀取時間1s
factory.setReadTimeout(1000);
return new RestTemplate(factory);
}
}在需要使用的地方使用@Resource或者@Autowired注入進來
@Resource private RestTemplate restTemplate;
然后我們平常調用第三方的接口是get方式和post方式,restTemplate提供getForEntity和postForEntity方法支持這兩種方式,直接調用即可,源碼分別如下:
getForEntity方法:
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = this.acceptHeaderRequestCallback(responseType);
ResponseExtractor<ResponseEntity<T>> responseExtractor = this.responseEntityExtractor(responseType);
return (ResponseEntity)nonNull(this.execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables));
}postForEntity方法:
public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = this.httpEntityCallback(request, responseType);
ResponseExtractor<ResponseEntity<T>> responseExtractor = this.responseEntityExtractor(responseType);
return (ResponseEntity)nonNull(this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables));
}源碼中還有很多以上兩種其他的重載方法,以上是作者平常項目中用的最多的一種,參數有url(第三方http鏈接)、request是請求所需的參數,responseType是返回類型里的泛型。
只需要解析返回的參數即可。
在平常的開發中,以上簡單的配置可能就夠用了,但是在高并發下,對接口響應時間要求很高,所以我們需要盡量的提高第三方接口響應時間。在RestTemplate中可以使用httpClient長連接,關于httpClient長連接的介紹我們可以參考:HTTPclient保持長連接
以下代碼我們設置了長連接預熱的功能,以及路由并發數:
@Slf4j
@Configuration
public class RestTemplateConfiguration {
@Bean(name = "restTemplate")
public RestTemplate restTemplate() {
return getRestTemplate(3, "https://www.baidu.com/......");
}
private RestTemplate getRestTemplate(int maxTotal, String preHeatUrl) {
HttpComponentsClientHttpRequestFactory httpRequestFactory = httpComponentsClientHttpRequestFactory(maxTotal);
RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
//解決首次預熱耗時長
if (StringUtils.isNotEmpty(preHeatUrl)) {
try {
restTemplate.postForEntity(preHeatUrl, "", String.class);
} catch (Exception e) {
log.error("preHeat url error:{}", e.getMessage());
}
}
return restTemplate;
}
/**
* ClientHttpRequestFactory接口的另一種實現方式(推薦使用),即:
* HttpComponentsClientHttpRequestFactory:底層使用Httpclient連接池的方式創建Http連接請求
*
* @return
*/
private HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(int maxTotal) {
//Httpclient連接池,長連接保持時間
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(1, TimeUnit.HOURS);
//設置總連接數
connectionManager.setMaxTotal(maxTotal);
//設置同路由的并發數
connectionManager.setDefaultMaxPerRoute(maxTotal);
//設置header
List<Header> headers = new ArrayList<Header>();
headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04"));
headers.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"));
headers.add(new BasicHeader("Connection", "keep-alive"));
//創建HttpClient
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connectionManager)
.setDefaultHeaders(headers)
.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) //設置重試次數
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) //設置保持長連接
.build();
//創建HttpComponentsClientHttpRequestFactory實例
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient);
//設置客戶端和服務端建立連接的超時時間
requestFactory.setConnectTimeout(10000);
//設置客戶端從服務端讀取數據的超時時間
requestFactory.setReadTimeout(5000);
//設置從連接池獲取連接的超時時間,不宜過長
requestFactory.setConnectionRequestTimeout(2000);
//緩沖請求數據,默認為true。通過POST或者PUT大量發送數據時,建議將此更改為false,以免耗盡內存
requestFactory.setBufferRequestBody(false);
return requestFactory;
}我們可以看到,在getRestTemplate方法中,
return restTemplate;
之前先請求了一次,也就是說在需要使用第三方接口調用的service層注入的時候,提前先調用了一次,根據長連接的特性,一般第一次連接的時間較長,使用完之后,這個連接并不會馬上回收掉,在一定的時間還是存活狀態,所以在高并發下,經過預熱后的接口響應時間會大幅提高。
我們可以看到以下代碼
//設置總連接數 connectionManager.setMaxTotal(maxTotal);
我們可以看到這一行,maxTotal是設置總連接數,這個設置需要根據接口的響應時間以及需要支持的QPS來設置,比如接口響應時間是100ms,需要支持的QPS為5000,也就是5000/s,那么一個長連接1s就是能夠處理10個請求,那么總共需要maxTotal為500個,這個就是設置的大概數量,但是有時候QPS不是那么穩定,所以具體設置多少得視具體情況而定。
RestTemplate深度解析可以參考:RestTemplate深度解析
到此,關于“java實用型高并發下RestTemplate的正確使用方法是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。