在進行超時時間設置之前我們需要了解一次http請求經歷的過程
- 瀏覽器進行DNS域名解析,得到對應的IP地址
- 根據這個IP,找到對應的服務器建立連接(三次握手)
- 建立TCP連接后發起HTTP請求(一個完整的http請求報文)
- 服務器響應HTTP請求,返回數據(服務器如何響應)
- 客戶端對頁面進行渲染呈現給用戶
- 服務器關閉TCP連接(四次揮手)
在客戶端和服務器之間通常有一層網關來負責路由和負載均衡:
DNS和TCP的超時時間通常由系統指定,DNS默認為5s,TCP建了超時默認為127s
所以下面從客戶端、網關、服務端三個方面來講解下HTTP請求的超時時間設置:
1、客戶端設置
以JS為例
(1)使用XMLHttpRequest
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/api', true);// 設置超時時間,單位是毫秒
xhr.timeout = 2000; // 2秒后超時// 定義超時處理邏輯
xhr.ontimeout = function () {console.error("The request for " + url + " timed out.");
};xhr.onload = function () {// 請求成功的處理邏輯if (xhr.status >= 200 && xhr.status < 300) {console.log('The request was successful!', xhr.responseText);} else {console.error('The request failed!', xhr.status);}
};xhr.onerror = function () {// 請求失敗的處理邏輯console.error('The request encountered an error.');
};xhr.send();
(2)使用fetch
const url = 'http://example.com/api';// 設置超時時間
const timeout = 2000; // 2秒后超時// 創建一個超時的Promise
const timeoutPromise = new Promise((resolve, reject) => {setTimeout(() => {reject(new Error('Request timed out'));}, timeout);
});// 發起fetch請求
const fetchPromise = fetch(url);// 使用Promise.race同時執行請求和超時Promise,哪個先完成就處理哪個
Promise.race([fetchPromise, timeoutPromise]).then(response => {// 檢查是否響應成功if (!response.ok) {throw new Error('Network response was not ok');}return response.text();}).then(data => {// 請求成功的處理邏輯console.log('The request was successful!', data);}).catch(error => {// 請求失敗或超時的處理邏輯console.error('Failed!', error);});
2、網關超時時間設置
以nginx為例:
在nginx.conf配置文件中可以指定超時時間
server {location / {proxy_pass http://backend_server;proxy_connect_timeout 5s;proxy_read_timeout 10s;proxy_send_timeout 5s;}
}
其中:
-
連接超時(Connection Timeout): 這是指客戶端嘗試與服務器建立連接時的最大等待時間。如果在這個時間內沒有建立連接(例如,服務器沒有響應或者網絡延遲很高),客戶端就會放棄嘗試并拋出一個超時異常。
-
讀超時(Read Timeout): 讀超時是指客戶端與服務器連接成功后,等待服務器發送數據的最大時間。如果在這個時間內客戶端沒有收到任何數據,就會認為讀取操作超時并拋出異常。這通常發生在服務器處理請求的時間過長,或者網絡傳輸延遲導致數據包遲遲未到達客戶端。
-
寫超時(Write Timeout): 寫超時是指在客戶端嘗試向服務器發送數據時的最大等待時間。如果客戶端在這段時間內未能完成數據的發送,就會認為寫操作超時。這可能是因為網絡速度慢或者服務器處理寫入請求的速度慢。
3、服務端超時時間設置
以Tomcat為例:
可以在server.xml
文件中指定服務器的超時時間,如下所示:
<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"readTimeout="15000"writeTimeout="15000" />