一文探索Apache HttpClient如何設(shè)定超時(shí)時(shí)間
最近在項(xiàng)目遇到了通過HTTP請求,調(diào)用第三方接口的問題。
一、Apache HttpClient模擬POST請求,調(diào)用第三方接口
Apache HttpClient是一個(gè)流行的Java庫,用于發(fā)送HTTP請求。
我們可以使用該庫來模擬POST請求。
1、發(fā)起POST請求
@Controller
@RequestMapping("/client")
public class TestController {
private static final String url = "http://127.0.0.1:8080/MyProject/nezha/getUser";
@RequestMapping(value = "/getUser", method = RequestMethod.POST)
@ResponseBody
public User getUser(@RequestBody User user) {
System.out.println("請求參數(shù):"+user);
String json = JSON.toJSONString(user);
String userRet = HttpUtil.sendHttpPost(url, json);
User ret = JSON.toJavaObject(JSONObject.parseObject(userRet), User.class);
System.out.println("HttpPost方式發(fā)送POST請求:"+ret);
return ret;
}
}
2、模擬服務(wù)端
@Controller
@RequestMapping("/server")
public class PostServerController {
@RequestMapping(value = "/getUser", method = RequestMethod.POST)
@ResponseBody
public User getUser(@RequestBody User user) {
user.setInfo("getUser,我 OK 啦");
System.out.println(user);
return user;
}
}
3、通過postman測試一下

4、Apache HttpClient
public class HttpUtil {
/**
* HttpPost方式
* 發(fā)送POST請求
*/
public static String sendHttpPost(String url, String data) {
String response = null;
try {
CloseableHttpClient httpclient = null;
CloseableHttpResponse httpresponse = null;
try {
httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000) //連接超時(shí)時(shí)間
.setSocketTimeout(5000) //讀取數(shù)據(jù)超時(shí)時(shí)間
.build();
httppost.setConfig(requestConfig);
StringEntity stringentity = new StringEntity(data, ContentType.create("application/json", "UTF-8"));
httppost.setEntity(stringentity);
httpresponse = httpclient.execute(httppost);
response = EntityUtils.toString(httpresponse.getEntity());
} finally {
if (httpclient != null) {
httpclient.close();
}
if (httpresponse != null) {
httpresponse.close();
}
}
} catch (Exception e) {
return null;
}
return response;
}
}
大家注意到了嗎?HttpClient需要配置一個(gè)連接超時(shí)時(shí)間和讀取數(shù)據(jù)超時(shí)時(shí)間。在配置的時(shí)候,我也是根據(jù)以往的經(jīng)驗(yàn),大概的配置了一下,這個(gè)數(shù)值怎么界定,也是沒有一個(gè)準(zhǔn)確的說法。
二、HTTP超時(shí)時(shí)間
1、眾所周知,HTTP使用的是TCP/IP 協(xié)議
TCP/IP協(xié)議是能夠?qū)崿F(xiàn)多個(gè)不同網(wǎng)絡(luò)間信息傳輸?shù)膮f(xié)議簇,它包括以下幾個(gè)主要的協(xié)議:
- 傳輸控制協(xié)議(TCP):是一種面向連接的協(xié)議,它提供了一種可靠的數(shù)據(jù)傳輸服務(wù),通過序列號、確認(rèn)號、重傳和流量控制等機(jī)制來實(shí)現(xiàn)數(shù)據(jù)的傳輸。
- 互聯(lián)網(wǎng)協(xié)議(IP):是一種無連接協(xié)議,它負(fù)責(zé)將數(shù)據(jù)分組在網(wǎng)絡(luò)上進(jìn)行傳輸。IP協(xié)議通過將數(shù)據(jù)分組封裝在一個(gè)個(gè)數(shù)據(jù)包中,并在每個(gè)數(shù)據(jù)包中包含源地址和目的地址,來實(shí)現(xiàn)數(shù)據(jù)在網(wǎng)絡(luò)上的傳輸。
- 用戶數(shù)據(jù)報(bào)協(xié)議(UDP):是一種無連接協(xié)議,它提供了一種簡單的數(shù)據(jù)傳輸服務(wù),但是它并不能保證數(shù)據(jù)的可靠性和順序。UDP通常用于一些不需要可靠傳輸?shù)膱鼍?,例如音頻和視頻流傳輸?shù)取?/li>
- 地址解析協(xié)議(ARP):該協(xié)議用于將網(wǎng)絡(luò)層的IP地址解析為數(shù)據(jù)鏈路層的MAC地址。
- 反向地址解析協(xié)議(RARP):該協(xié)議用于將數(shù)據(jù)鏈路層的MAC地址解析為網(wǎng)絡(luò)層的IP地址。
- 動(dòng)態(tài)主機(jī)配置協(xié)議(DHCP):該協(xié)議用于動(dòng)態(tài)地分配IP地址和其他網(wǎng)絡(luò)配置參數(shù)。
- 網(wǎng)絡(luò)時(shí)間協(xié)議(NTP):該協(xié)議用于在網(wǎng)絡(luò)上同步時(shí)間。
- 簡單郵件傳輸協(xié)議(SMTP):該協(xié)議用于在網(wǎng)絡(luò)上傳輸電子郵件。
- 文件傳輸協(xié)議(FTP):該協(xié)議用于在網(wǎng)絡(luò)上進(jìn)行文件傳輸。
除了上述協(xié)議外,TCP/IP協(xié)議簇還包括其他一些協(xié)議,如Telnet、SNMP、HTTP、HTTPS等。這些協(xié)議在不同的應(yīng)用場景中發(fā)揮著重要的作用。
2、TCP/IP超時(shí)時(shí)間設(shè)置
TCP/IP協(xié)議中的超時(shí)時(shí)間是指網(wǎng)絡(luò)在傳輸數(shù)據(jù)時(shí),等待數(shù)據(jù)包返回確認(rèn)信息的時(shí)間。具體來說,當(dāng)一個(gè)數(shù)據(jù)包被發(fā)送到網(wǎng)絡(luò)中后,發(fā)送方會(huì)等待接收方的確認(rèn)信息,以確定數(shù)據(jù)包是否已經(jīng)被成功接收。如果超過了一定的時(shí)間,還沒有收到確認(rèn)信息,那么發(fā)送方就會(huì)認(rèn)為數(shù)據(jù)包已經(jīng)丟失,然后會(huì)重新發(fā)送數(shù)據(jù)包。這個(gè)一定的時(shí)間就是TCP/IP協(xié)議中的超時(shí)時(shí)間。
TCP/IP協(xié)議中的超時(shí)時(shí)間可以通過“重試次數(shù)”和“初始超時(shí)時(shí)間”來設(shè)置。重試次數(shù)是指發(fā)送方在未收到確認(rèn)信息時(shí),重新發(fā)送數(shù)據(jù)包的次數(shù);初始超時(shí)時(shí)間是指發(fā)送方等待確認(rèn)信息的初始時(shí)間。這兩個(gè)參數(shù)通??梢愿鶕?jù)具體情況進(jìn)行調(diào)整,以滿足不同的網(wǎng)絡(luò)傳輸需求。
一般來說,TCP/IP協(xié)議中的超時(shí)時(shí)間應(yīng)該在幾百毫秒到幾秒之間。具體的時(shí)間取決于網(wǎng)絡(luò)狀況、數(shù)據(jù)包的大小以及數(shù)據(jù)傳輸?shù)木嚯x等因素。如果超時(shí)時(shí)間設(shè)置得太短,可能會(huì)導(dǎo)致不必要的重試次數(shù),浪費(fèi)網(wǎng)絡(luò)資源;如果超時(shí)時(shí)間設(shè)置得太長,可能會(huì)導(dǎo)致傳輸延遲,影響網(wǎng)絡(luò)性能。因此,在設(shè)置TCP/IP協(xié)議中的超時(shí)時(shí)間時(shí),需要根據(jù)具體情況進(jìn)行綜合考慮。
3、HTTP連接超時(shí)時(shí)間如何設(shè)置
一般來說,TCP 三次握手建立連接需要的時(shí)間非常短,一般都在毫秒級。
如果十幾秒、甚至幾十秒都無法連接,很可能是網(wǎng)絡(luò)問題或者防火墻問題,大概率是永遠(yuǎn)無法連接了。
因此連接超時(shí)時(shí)間一般不會(huì)設(shè)置的太大,2-6秒即可。
需要注意的是,現(xiàn)在的程序開發(fā)中,一般都是使用Nginx 的反向代理來負(fù)載均衡,客戶端連接的其實(shí)是 Nginx,而不是服務(wù)端。
4、HTTP讀取超時(shí)時(shí)間如何設(shè)置
(1)先理解一下什么是讀取超時(shí)?
一般來說,連接超時(shí),指的就是網(wǎng)絡(luò)連接超時(shí)。
那么讀取超時(shí)呢?
在我看來,讀取超時(shí)包括了Http請求的網(wǎng)絡(luò)時(shí)間+服務(wù)端接口處理業(yè)務(wù)邏輯的時(shí)間+數(shù)據(jù)返回的網(wǎng)絡(luò)時(shí)間。
因此,如果發(fā)生了讀取超時(shí),是無法判斷是網(wǎng)絡(luò)超時(shí)還是接口執(zhí)行超時(shí)的。
(2)讀取超時(shí)時(shí)間越大越好嗎?
很多小伙伴會(huì)有這樣的想法,那我將讀取超時(shí)時(shí)間設(shè)置的足夠大,足夠你網(wǎng)絡(luò)+業(yè)務(wù)執(zhí)行的時(shí)間了,不就萬事OK了嘛!
真的是這樣嗎?
一般情況下,Http請求都是同步調(diào)用,如果設(shè)置的足夠大,往往會(huì)影響客戶端程序的執(zhí)行效率,如果是高并發(fā)場景,后果不堪設(shè)想,異步的時(shí)候可以,這也是異步的應(yīng)用場景之一。
(3)讀取超時(shí)時(shí)間大于接口的執(zhí)行時(shí)間,第三方接口執(zhí)行會(huì)中斷嗎?
下面將讀取超時(shí)時(shí)間設(shè)置為5秒,為了模擬效果,將第三方接口的執(zhí)行時(shí)間設(shè)置為10秒。
也就是說讀取超時(shí)時(shí)間大于接口的執(zhí)行時(shí)間,沒等執(zhí)行完呢,因?yàn)樽x取超時(shí),Http請求斷開了。
此時(shí),第三方接口執(zhí)行會(huì)中斷嗎?
調(diào)用 client 接口后,從日志中可以看到,客戶端 5 秒后出現(xiàn)了 SocketTimeoutException,原因是讀取超時(shí),第三方接口卻絲毫沒受影響在 5 秒后執(zhí)行完成。
眾所周知,Tomcat的web服務(wù)器是將請求提交到線程池執(zhí)行的,只要服務(wù)端收到了請求,網(wǎng)絡(luò)層的超時(shí)和斷開不會(huì)影響服務(wù)端的執(zhí)行。
說了這么多,HTTP讀取超時(shí)時(shí)間如何設(shè)置?
就像一開始的時(shí)候說的,根據(jù)程序的實(shí)際情況和性能要求進(jìn)行設(shè)置,沒有一個(gè)明確的標(biāo)準(zhǔn)。
到此這篇關(guān)于一文探索Apache HttpClient如何設(shè)定超時(shí)時(shí)間的文章就介紹到這了,更多相關(guān)Apache HttpClient超時(shí)時(shí)間內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實(shí)現(xiàn)獲取客戶端IP地理位置
在當(dāng)今互聯(lián)的世界中,了解客戶端的地理位置對于提供個(gè)性化服務(wù)和增強(qiáng)用戶體驗(yàn)至關(guān)重要,使用本文為大家介紹了SpringBoot獲取客戶端IP地理位置的相關(guān)方法,需要的小伙伴可以參考下2023-11-11
Java連接Oracle數(shù)據(jù)庫實(shí)例解析
數(shù)據(jù)庫的操作是當(dāng)前系統(tǒng)開發(fā)必不可少的開發(fā)部分之一。接下來通過本文給大家介紹Java連接Oracle數(shù)據(jù)庫實(shí)例解析,非常不錯(cuò)具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-06-06
詳解springmvc控制登錄用戶session失效后跳轉(zhuǎn)登錄頁面
本篇文章主要介紹了springmvc控制登錄用戶session失效后跳轉(zhuǎn)登錄頁面,session一旦失效就需要重新登陸,有興趣的同學(xué)可以了解一下。2017-01-01
spring boot如何使用spring AOP實(shí)現(xiàn)攔截器
本篇文章主要介紹了spring boot如何使用spring AOP實(shí)現(xiàn)攔截器,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04
使用Springboot實(shí)現(xiàn)OAuth服務(wù)的示例詳解
OAuth(Open Authorization)是一個(gè)開放標(biāo)準(zhǔn),用于授權(quán)第三方應(yīng)用程序訪問用戶資源,而不需要共享用戶憑證。本文主要介紹了如何使用Springboot實(shí)現(xiàn)一個(gè)OAuth服務(wù),需要的可以參考一下2023-05-05
Java ShardingJDBC實(shí)戰(zhàn)演練
Sharding-JDBC 采用在 JDBC 協(xié)議層擴(kuò)展分庫分表,是一個(gè)以 jar 形式提供服務(wù)的輕量級組件,其核心思路是小而美地完成最核心的事情2021-11-11
Java項(xiàng)目實(shí)現(xiàn)尋找迷宮出路
這篇文章主要為大家詳細(xì)介紹了Java項(xiàng)目實(shí)現(xiàn)尋找迷宮出路,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05

