httpclient逾時時間
說明
ConnectionRequestTimeout
httpclient使用串連池來管理串連,這個時間就是從串連池擷取串連的逾時時間,可以想象下資料庫連接池 ConnectTimeout
串連建立時間,三向交握完成時間 SocketTimeout
資料轉送過程中資料包之間間隔的最大時間
下面重點說下SocketTimeout,比如有如下圖所示的http請求
雖然報文(“abc”)返回總共用了6秒,如果SocketTimeout設定成4秒,實際程式執行的時候是不會拋出java.net.SocketTimeoutException: Read timed out異常的。
因為SocketTimeout的值表示的是“a”、”b”、”c”這三個報文,每兩個相鄰的報文的間隔時間不能超過SocketTimeout。 程式驗證: server端(python3):每隔3秒返回a、b、c
__author__ = 'yanglikun'from flask import Flaskfrom flask import Responseimport timeapp = Flask(__name__)@app.route("/")def hello(): def generate(): for row in ["a","b","c"]: time.sleep(3) yield row; return Response(generate());if __name__ == "__main__": app.run(host='0.0.0.0',port=8897)
java用戶端(httpclient 4.3.6)
CloseableHttpClient client = HttpClientBuilder.create().build(); RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(5) .setConnectTimeout(5) .setSocketTimeout(6000).build(); HttpGet httpGet = new HttpGet("http://192.168.147.90:8897/"); httpGet.setConfig(config); long begin = System.currentTimeMillis(); String respStr = null; try { CloseableHttpResponse resp = client.execute(httpGet); respStr = EntityUtils.toString(resp.getEntity()); } catch (IOException e) { e.printStackTrace(); } System.err.println("respStr:" + respStr); System.err.println("end:" + (System.currentTimeMillis() - begin));
用戶端執行結果
雖然設定SocketTimeout為6000(6秒),但是程式執行了9秒,也沒有拋出java.net.SocketTimeoutException: Read timed out異常
wireshark抓包結果
可能會想實際的報文是不是每經過3秒返回一個報文呢,下面是通過wireshark抓包的結果
其中
1:返回字母a的TCP報文
2:返回字母b的TCP報文
3:返回字母c的TCP報文
根據time列可以看出TCP資料轉送報文之間的間隔就是python程式裡面寫的 3秒。BTW,可以複習下TCP的另一個知識,每個報文後還有一個ACK的報文,就是tcp用戶端的回執報文
點擊查看大圖