高并發(fā)下restTemplate的錯(cuò)誤分析方式
高并發(fā)下restTemplate的錯(cuò)誤分析
1. 問題現(xiàn)象和分析
org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection
此問題很明顯是連接等待超時(shí),而且是從連接池中獲取的連接。
那么就有一個(gè)很詫異的問題,這里哪來的連接池呢?然后我去跟蹤restTemplate的源碼發(fā)現(xiàn),其底層是通過apache 的httpClient實(shí)現(xiàn)了連接池。那么問題就很明顯了。就是在并發(fā)量高的時(shí)候,可能會(huì)出現(xiàn)連接池不夠用。
2. 問題解決
- 既然分析出來是連接池不夠了,那么我們在構(gòu)建restTemplate的時(shí)候配置其底層的httpClient連接池大小,以便提高高并發(fā)的時(shí)候RestTemplate的性能。
- 可以通過配置總體最大連接池(maxConnTotal)和單個(gè)路由連接最大數(shù)(maxConnPerRoute),默認(rèn)是(20,2)
maxConnTotal
是整個(gè)連接池的大小,根據(jù)自己的業(yè)務(wù)需求進(jìn)行設(shè)置
maxConnPerRoute
是單個(gè)路由連接的最大數(shù),可以根據(jù)自己的業(yè)務(wù)需求進(jìn)行設(shè)置
public RestTemplate restTemplate() { HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create() .setMaxConnTotal(20) .setMaxConnPerRoute(20) .build()); httpRequestFactory.setConnectionRequestTimeout(10000); httpRequestFactory.setConnectTimeout(10000); httpRequestFactory.setReadTimeout(10000); return new RestTemplate(httpRequestFactory); }
這樣就可以解決高并發(fā)下restTemplate連接池不夠的問題。提高其性能,使得調(diào)用restTemplate的程序性能------>
使用restTemplate出現(xiàn)的異常
1.org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class zycf.cloud.bean.SafetyResponseType] and content type [text/html]
除了所有的答案之外,如果碰巧收到了text/html,而你期望別的東西(即 application/json)
則可能表明服務(wù)器端發(fā)生了錯(cuò)誤(比如404)并且返回了錯(cuò)誤頁面而不是你的數(shù)據(jù)。
用postMan測試,果然是的,這個(gè)接口期望收到j(luò)son數(shù)據(jù),卻收到了HTML頁面
2.org.springframework.web.client.RestClientException: No HttpMessageConverter for java.util.HashMap and content type "multipart/form-data"
HashMap參數(shù)改為LinkedMultiValueMap
MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("clientId",ZHEJIANG_CLIENT_ID ); params.add("nonce", uuid); //隨機(jī)數(shù) params.add("timestamp", dateString); //時(shí)間戳 params.add("signature", signature); //簽名 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers); /** 發(fā)送請(qǐng)求*/ RestTemplate restTemplate = new RestTemplate(); SafetyResponseType safetyResponseType = restTemplate.postForObject(SAFETY_CERTIFICATE_URL, requestEntity, SafetyResponseType.class );
采用這種方法反序列化的時(shí)候,如果json字符串中有相同的key,存的時(shí)候值會(huì)以數(shù)組的方式保存,
比如我們在做表單提交的時(shí)候,表單數(shù)據(jù)中可能存在鍵相同值不同的情況,可以用這種方法存值。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot中的聲明式事務(wù)+切面事務(wù)+編程式事務(wù)詳解
這篇文章主要介紹了SpringBoot中的聲明式事務(wù)+切面事務(wù)+編程式事務(wù)詳解,事務(wù)管理對(duì)于企業(yè)應(yīng)用來說是至關(guān)重要的,當(dāng)出現(xiàn)異常情況時(shí),它也可以保證數(shù)據(jù)的一致性,需要的朋友可以參考下2023-08-08SpringBoot實(shí)現(xiàn)網(wǎng)站的登陸注冊邏輯記錄
登陸注冊功能是我們?nèi)粘i_發(fā)中經(jīng)常遇到的一個(gè)功能,下面這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)網(wǎng)站的登陸注冊邏輯的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-10-10復(fù)雜JSON字符串轉(zhuǎn)換為Java嵌套對(duì)象的實(shí)現(xiàn)
這篇文章主要介紹了復(fù)雜JSON字符串轉(zhuǎn)換為Java嵌套對(duì)象的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09java實(shí)現(xiàn)合并兩個(gè)已經(jīng)排序的列表實(shí)例代碼
這篇文章主要介紹了java實(shí)現(xiàn)合并兩個(gè)已經(jīng)排序的列表實(shí)例代碼,有需要的朋友可以參考一下2013-12-12