新聞中心
?前言
不知道你有沒有過這樣的經(jīng)歷,你的Spring項目通過http接口遠(yuǎn)程調(diào)用外部系統(tǒng)時,通常你會設(shè)置超時時間,比如5秒鐘,但是實際情況卻是由于外部系統(tǒng)出現(xiàn)故障并導(dǎo)致連接超時,有些請求花費遠(yuǎn)遠(yuǎn)超過5秒時間,甚至1分鐘,這直接導(dǎo)致你本身的接口響應(yīng)很慢,如果訪問你接口的流量很大的話,甚至拖垮你的系統(tǒng),這將會是災(zāi)難性的后果。

成都創(chuàng)新互聯(lián)專注于普蘭企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站設(shè)計,商城網(wǎng)站制作。普蘭網(wǎng)站建設(shè)公司,為普蘭等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站制作,專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
你可能會好奇到底是什么原因?qū)е碌模芸赡苁悄愫雎粤诉@個超時配置項connectionRequestTimeout導(dǎo)致的。
Spring中的連接池
在深入了解 connectionRequestTimeout 之前,我們需要了解外部 HTTP 請求是如何在 Spring 中進(jìn)行的。
Spring 通過Http調(diào)用外部系統(tǒng)的時候,會使用連接池去管理他們。因為HTTP請求創(chuàng)建連接代價比較高,而連接池可以做到連接的復(fù)用,回過頭,我們思考下為什么會代價高呢?
- DNS 解析:在建立連接之前,客戶端必須首先使用域名系統(tǒng) (DNS) 將服務(wù)器的域名解析為 IP 地址。DNS 解析可能需要時間,尤其是在客戶端的 DNS 緩存很冷且服務(wù)器的域名尚未緩存的情況下。
- TCP 握手:確定服務(wù)器的 IP 地址后,客戶端必須與服務(wù)器建立 TCP 連接。這涉及三次握手過程,這可能會花費時間并增加請求的開銷。
- SSL/TLS 協(xié)商:如果服務(wù)器使用 HTTPS,客戶端還必須在可以交換任何數(shù)據(jù)之前與服務(wù)器協(xié)商 SSL/TLS 連接。這涉及一個復(fù)雜的握手過程,可能會增加請求的大量開銷。
為 HTTP 請求使用連接池可以顯著提高性能。但是,我們需要對其進(jìn)行適當(dāng)配置以防止出現(xiàn)災(zāi)難情況。
什么是連接請求超時?
現(xiàn)在讓我們用連接池的概念再來看問題。
本例中B組件是外部系統(tǒng),處于無法建立HTTP連接的情況,導(dǎo)致A中的連接超時,請仔細(xì)看上面A指向連接池的箭頭,A 正在等待另一個連接來建立到 B 的 HTTP 連接。
connectionRequestTimeout 是 Spring 中的一個配置參數(shù),用于確定客戶端在超時前等待來自連接池的連接的時間。此超時值用于防止客戶端無限期地等待可能不可用的連接,并在不再需要時釋放連接池中的資源。
API 響應(yīng)時間 = connectionRequestTimeout? + connectionTimeout? + readTimeout 。
- connectionRequestTimeout:等待從連接池獲取連接的時間。
- connectionTimeout:等待與外部組件建立連接的時間。
- readTimeout:等待外部組件響應(yīng)的時間。
如何設(shè)置connectionRequestTimeout?
connectionRequestTimeout 的默認(rèn)值為 -1,這意味著它無限期地等待來自連接池的連接。由于我們希望避免外部組件中斷導(dǎo)致系統(tǒng)故障,因此我們需要為其設(shè)置一個顯式值。
假設(shè)您將值設(shè)置得太短:1 秒。如果系統(tǒng)需要高延遲,這可能是一個頻繁的故障,因為它可能一直渴望連接。另一方面,如果該值太長,比如 10 分鐘,系統(tǒng)很容易因外部故障而失敗。
因此,你需要統(tǒng)計系統(tǒng)的API響應(yīng)時間, 最大超時響應(yīng)時間如下:
API 響應(yīng)時間 = connectionRequestTimeout + connectionTimeout + readTimeout。
看看是否有很多請求超過了connectionTimeout和readTimeout?之和, 如果是這樣的話,系統(tǒng)需要增大連接池的大小或者減小connectionRequestTimeout?值。否則就將 connectionRequestTimeout 合理設(shè)置為 15 秒到 30 秒之間。
下面是設(shè)置 connectionRequestTimeout 的示例代碼。
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
public class ConnectionRequestTimeoutExample {
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
// Set the connectionRequestTimeout value to 10 seconds
requestFactory.setConnectionRequestTimeout(10000);
restTemplate.setRequestFactory(requestFactory);
...
}
}
在這個例子中,我們創(chuàng)建了一個新的RestTemplate?和一個新的HttpComponentsClientHttpRequestFactory?,然后我們connectionRequestTimeout?使用該方法將該值設(shè)置為 10 秒,并使用該方法為 RestTemplate? 設(shè)置請求工廠setRequestFactory()。
總結(jié)
最后,我們在總結(jié)以下Spring中Http請求的3個關(guān)鍵的超時配置吧,其中connectionRequestTimeout 最容易被忽視的。
- connectionRequestTimeout:等待從連接池獲取連接的時間
- connectionTimeout:等待與外部組件建立連接的時間
- readTimeout:等待外部組件響應(yīng)的時間
新聞標(biāo)題:Spring項目不要忽視這個超時配置,否則你的Http調(diào)用可能無法結(jié)束
路徑分享:http://www.dlmjj.cn/article/dpsdcec.html


咨詢
建站咨詢
