一文探索Apache HttpClient如何設(shè)定超時時間
最近在項目遇到了通過HTTP請求,調(diào)用第三方接口的問題。
一、Apache HttpClient模擬POST請求,調(diào)用第三方接口
Apache HttpClient是一個流行的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) //連接超時時間 .setSocketTimeout(5000) //讀取數(shù)據(jù)超時時間 .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需要配置一個連接超時時間和讀取數(shù)據(jù)超時時間。在配置的時候,我也是根據(jù)以往的經(jīng)驗,大概的配置了一下,這個數(shù)值怎么界定,也是沒有一個準(zhǔn)確的說法。
二、HTTP超時時間
1、眾所周知,HTTP使用的是TCP/IP 協(xié)議
TCP/IP協(xié)議是能夠?qū)崿F(xiàn)多個不同網(wǎng)絡(luò)間信息傳輸?shù)膮f(xié)議簇,它包括以下幾個主要的協(xié)議:
- 傳輸控制協(xié)議(TCP):是一種面向連接的協(xié)議,它提供了一種可靠的數(shù)據(jù)傳輸服務(wù),通過序列號、確認(rèn)號、重傳和流量控制等機制來實現(xiàn)數(shù)據(jù)的傳輸。
- 互聯(lián)網(wǎng)協(xié)議(IP):是一種無連接協(xié)議,它負(fù)責(zé)將數(shù)據(jù)分組在網(wǎng)絡(luò)上進(jìn)行傳輸。IP協(xié)議通過將數(shù)據(jù)分組封裝在一個個數(shù)據(jù)包中,并在每個數(shù)據(jù)包中包含源地址和目的地址,來實現(xiàn)數(shù)據(jù)在網(wǎng)絡(luò)上的傳輸。
- 用戶數(shù)據(jù)報協(xié)議(UDP):是一種無連接協(xié)議,它提供了一種簡單的數(shù)據(jù)傳輸服務(wù),但是它并不能保證數(shù)據(jù)的可靠性和順序。UDP通常用于一些不需要可靠傳輸?shù)膱鼍埃缫纛l和視頻流傳輸?shù)取?/li>
- 地址解析協(xié)議(ARP):該協(xié)議用于將網(wǎng)絡(luò)層的IP地址解析為數(shù)據(jù)鏈路層的MAC地址。
- 反向地址解析協(xié)議(RARP):該協(xié)議用于將數(shù)據(jù)鏈路層的MAC地址解析為網(wǎng)絡(luò)層的IP地址。
- 動態(tài)主機配置協(xié)議(DHCP):該協(xié)議用于動態(tài)地分配IP地址和其他網(wǎng)絡(luò)配置參數(shù)。
- 網(wǎng)絡(luò)時間協(xié)議(NTP):該協(xié)議用于在網(wǎng)絡(luò)上同步時間。
- 簡單郵件傳輸協(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è)置
TCP/IP協(xié)議中的超時時間是指網(wǎng)絡(luò)在傳輸數(shù)據(jù)時,等待數(shù)據(jù)包返回確認(rèn)信息的時間。具體來說,當(dāng)一個數(shù)據(jù)包被發(fā)送到網(wǎng)絡(luò)中后,發(fā)送方會等待接收方的確認(rèn)信息,以確定數(shù)據(jù)包是否已經(jīng)被成功接收。如果超過了一定的時間,還沒有收到確認(rèn)信息,那么發(fā)送方就會認(rèn)為數(shù)據(jù)包已經(jīng)丟失,然后會重新發(fā)送數(shù)據(jù)包。這個一定的時間就是TCP/IP協(xié)議中的超時時間。
TCP/IP協(xié)議中的超時時間可以通過“重試次數(shù)”和“初始超時時間”來設(shè)置。重試次數(shù)是指發(fā)送方在未收到確認(rèn)信息時,重新發(fā)送數(shù)據(jù)包的次數(shù);初始超時時間是指發(fā)送方等待確認(rèn)信息的初始時間。這兩個參數(shù)通??梢愿鶕?jù)具體情況進(jìn)行調(diào)整,以滿足不同的網(wǎng)絡(luò)傳輸需求。
一般來說,TCP/IP協(xié)議中的超時時間應(yīng)該在幾百毫秒到幾秒之間。具體的時間取決于網(wǎng)絡(luò)狀況、數(shù)據(jù)包的大小以及數(shù)據(jù)傳輸?shù)木嚯x等因素。如果超時時間設(shè)置得太短,可能會導(dǎo)致不必要的重試次數(shù),浪費網(wǎng)絡(luò)資源;如果超時時間設(shè)置得太長,可能會導(dǎo)致傳輸延遲,影響網(wǎng)絡(luò)性能。因此,在設(shè)置TCP/IP協(xié)議中的超時時間時,需要根據(jù)具體情況進(jìn)行綜合考慮。
3、HTTP連接超時時間如何設(shè)置
一般來說,TCP 三次握手建立連接需要的時間非常短,一般都在毫秒級。
如果十幾秒、甚至幾十秒都無法連接,很可能是網(wǎng)絡(luò)問題或者防火墻問題,大概率是永遠(yuǎn)無法連接了。
因此連接超時時間一般不會設(shè)置的太大,2-6秒即可。
需要注意的是,現(xiàn)在的程序開發(fā)中,一般都是使用Nginx 的反向代理來負(fù)載均衡,客戶端連接的其實是 Nginx,而不是服務(wù)端。
4、HTTP讀取超時時間如何設(shè)置
(1)先理解一下什么是讀取超時?
一般來說,連接超時,指的就是網(wǎng)絡(luò)連接超時。
那么讀取超時呢?
在我看來,讀取超時包括了Http請求的網(wǎng)絡(luò)時間+服務(wù)端接口處理業(yè)務(wù)邏輯的時間+數(shù)據(jù)返回的網(wǎng)絡(luò)時間。
因此,如果發(fā)生了讀取超時,是無法判斷是網(wǎng)絡(luò)超時還是接口執(zhí)行超時的。
(2)讀取超時時間越大越好嗎?
很多小伙伴會有這樣的想法,那我將讀取超時時間設(shè)置的足夠大,足夠你網(wǎng)絡(luò)+業(yè)務(wù)執(zhí)行的時間了,不就萬事OK了嘛!
真的是這樣嗎?
一般情況下,Http請求都是同步調(diào)用,如果設(shè)置的足夠大,往往會影響客戶端程序的執(zhí)行效率,如果是高并發(fā)場景,后果不堪設(shè)想,異步的時候可以,這也是異步的應(yīng)用場景之一。
(3)讀取超時時間大于接口的執(zhí)行時間,第三方接口執(zhí)行會中斷嗎?
下面將讀取超時時間設(shè)置為5秒,為了模擬效果,將第三方接口的執(zhí)行時間設(shè)置為10秒。
也就是說讀取超時時間大于接口的執(zhí)行時間,沒等執(zhí)行完呢,因為讀取超時,Http請求斷開了。
此時,第三方接口執(zhí)行會中斷嗎?
調(diào)用 client 接口后,從日志中可以看到,客戶端 5 秒后出現(xiàn)了 SocketTimeoutException,原因是讀取超時,第三方接口卻絲毫沒受影響在 5 秒后執(zhí)行完成。
眾所周知,Tomcat的web服務(wù)器是將請求提交到線程池執(zhí)行的,只要服務(wù)端收到了請求,網(wǎng)絡(luò)層的超時和斷開不會影響服務(wù)端的執(zhí)行。
說了這么多,HTTP讀取超時時間如何設(shè)置?
就像一開始的時候說的,根據(jù)程序的實際情況和性能要求進(jìn)行設(shè)置,沒有一個明確的標(biāo)準(zhǔn)。
到此這篇關(guān)于一文探索Apache HttpClient如何設(shè)定超時時間的文章就介紹到這了,更多相關(guān)Apache HttpClient超時時間內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換詳解
這篇文章主要講解Java中基本數(shù)據(jù)類型的轉(zhuǎn)換,數(shù)據(jù)之間相互轉(zhuǎn)換是經(jīng)常會用到的基礎(chǔ)操作,文中講的很清晰,希望能給大家做一個參考。2022-05-05Java8函數(shù)式接口UnaryOperator用法示例
這篇文章主要介紹了Java8函數(shù)式接口UnaryOperator用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07詳解idea文件右鍵創(chuàng)建New沒有Create New Servlet的解決辦法
這篇文章主要介紹了詳解idea文件右鍵創(chuàng)建New沒有Create New Servlet的解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12java連接mysql數(shù)據(jù)庫學(xué)習(xí)示例
這篇文章主要介紹了java連接mysql數(shù)據(jù)庫學(xué)習(xí)示例,需要的朋友可以參考下2014-03-03Java使用modbus-master-tcp實現(xiàn)modbus tcp通訊
這篇文章主要為大家詳細(xì)介紹了另外一種Java語言的modbux tcp通訊方案,那就是modbus-master-tcp,文中的示例代碼講解詳細(xì),需要的可以了解下2023-12-12