一文探索Apache HttpClient如何設(shè)定超時(shí)時(shí)間
最近在項(xiàng)目遇到了通過HTTP請(qǐng)求,調(diào)用第三方接口的問題。
一、Apache HttpClient模擬POST請(qǐng)求,調(diào)用第三方接口
Apache HttpClient是一個(gè)流行的Java庫(kù),用于發(fā)送HTTP請(qǐng)求。
我們可以使用該庫(kù)來模擬POST請(qǐng)求。
1、發(fā)起POST請(qǐng)求
@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("請(qǐng)求參數(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請(qǐng)求:"+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測(cè)試一下
4、Apache HttpClient
public class HttpUtil { /** * HttpPost方式 * 發(fā)送POST請(qǐng)求 */ 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ù),通過序列號(hào)、確認(rèn)號(hào)、重傳和流量控制等機(jī)制來實(shí)現(xiàn)數(shù)據(jù)的傳輸。
- 互聯(lián)網(wǎng)協(xié)議(IP):是一種無(wú)連接協(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):是一種無(wú)連接協(xié)議,它提供了一種簡(jiǎn)單的數(shù)據(jù)傳輸服務(wù),但是它并不能保證數(shù)據(jù)的可靠性和順序。UDP通常用于一些不需要可靠傳輸?shù)膱?chǎng)景,例如音頻和視頻流傳輸?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í)間。
- 簡(jiǎn)單郵件傳輸協(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)用場(chǎ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è)置得太長(zhǎng),可能會(huì)導(dǎo)致傳輸延遲,影響網(wǎng)絡(luò)性能。因此,在設(shè)置TCP/IP協(xié)議中的超時(shí)時(shí)間時(shí),需要根據(jù)具體情況進(jìn)行綜合考慮。
3、HTTP連接超時(shí)時(shí)間如何設(shè)置
一般來說,TCP 三次握手建立連接需要的時(shí)間非常短,一般都在毫秒級(jí)。
如果十幾秒、甚至幾十秒都無(wú)法連接,很可能是網(wǎng)絡(luò)問題或者防火墻問題,大概率是永遠(yuǎn)無(wú)法連接了。
因此連接超時(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請(qǐng)求的網(wǎng)絡(luò)時(shí)間+服務(wù)端接口處理業(yè)務(wù)邏輯的時(shí)間+數(shù)據(jù)返回的網(wǎng)絡(luò)時(shí)間。
因此,如果發(fā)生了讀取超時(shí),是無(wú)法判斷是網(wǎng)絡(luò)超時(shí)還是接口執(zhí)行超時(shí)的。
(2)讀取超時(shí)時(shí)間越大越好嗎?
很多小伙伴會(huì)有這樣的想法,那我將讀取超時(shí)時(shí)間設(shè)置的足夠大,足夠你網(wǎng)絡(luò)+業(yè)務(wù)執(zhí)行的時(shí)間了,不就萬(wàn)事OK了嘛!
真的是這樣嗎?
一般情況下,Http請(qǐng)求都是同步調(diào)用,如果設(shè)置的足夠大,往往會(huì)影響客戶端程序的執(zhí)行效率,如果是高并發(fā)場(chǎng)景,后果不堪設(shè)想,異步的時(shí)候可以,這也是異步的應(yīng)用場(chǎ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請(qǐng)求斷開了。
此時(shí),第三方接口執(zhí)行會(huì)中斷嗎?
調(diào)用 client 接口后,從日志中可以看到,客戶端 5 秒后出現(xiàn)了 SocketTimeoutException,原因是讀取超時(shí),第三方接口卻絲毫沒受影響在 5 秒后執(zhí)行完成。
眾所周知,Tomcat的web服務(wù)器是將請(qǐng)求提交到線程池執(zhí)行的,只要服務(wù)端收到了請(qǐng)求,網(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換詳解
這篇文章主要講解Java中基本數(shù)據(jù)類型的轉(zhuǎn)換,數(shù)據(jù)之間相互轉(zhuǎn)換是經(jīng)常會(huì)用到的基礎(chǔ)操作,文中講的很清晰,希望能給大家做一個(gè)參考。2022-05-05Java8函數(shù)式接口UnaryOperator用法示例
這篇文章主要介紹了Java8函數(shù)式接口UnaryOperator用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07Spring Boot整合JWT的實(shí)現(xiàn)步驟
本文主要介紹了Spring Boot整合JWT,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08Spring MVC的文件上傳和下載以及攔截器的使用實(shí)例
這篇文章主要介紹了Spring MVC的文件上傳和下載以及攔截器的使用實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08詳解idea文件右鍵創(chuàng)建New沒有Create New Servlet的解決辦法
這篇文章主要介紹了詳解idea文件右鍵創(chuàng)建New沒有Create New Servlet的解決辦法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12java連接mysql數(shù)據(jù)庫(kù)學(xué)習(xí)示例
這篇文章主要介紹了java連接mysql數(shù)據(jù)庫(kù)學(xué)習(xí)示例,需要的朋友可以參考下2014-03-03Java使用modbus-master-tcp實(shí)現(xiàn)modbus tcp通訊
這篇文章主要為大家詳細(xì)介紹了另外一種Java語(yǔ)言的modbux tcp通訊方案,那就是modbus-master-tcp,文中的示例代碼講解詳細(xì),需要的可以了解下2023-12-12Java中Date時(shí)區(qū)的轉(zhuǎn)換代碼示例
這篇文章主要給大家介紹了關(guān)于Java中Date時(shí)區(qū)轉(zhuǎn)換的相關(guān)資料,當(dāng)在不同的時(shí)區(qū)使用相同程序,時(shí)間的值只會(huì)為當(dāng)?shù)貢r(shí)間,這樣就會(huì)造成時(shí)間混亂,需要的朋友可以參考下2023-07-07