摘要:問題現象在與第三方系統通過交互數據的過程中,抓包發現每次連接都是異常關閉,報文如下可以看到,由我方發起次握手建立連接,然后發送請求,對方響應數據,我方后直接發包圖中藍色陰影部分,將連接異常關閉,不僅沒有復用連接,且不是通過次揮手來關閉連接。
問題現象
在與第三方系統通過http交互數據的過程中,抓包發現每次TCP連接都是異常關閉,報文如下:
可以看到,由我方發起3次握手建立連接,然后發送http請求,對方響應數據,我方ACK后直接發RST包(圖中藍色陰影部分),將連接異常關閉,不僅沒有復用連接,且不是通過4次揮手來關閉連接。
關于RST包參考:http://blog.csdn.net/erlib/ar...
問題原因HttpClient 4.5.2 釋放連接API使用方式不正確
問題代碼如下(已簡化):
private boolean isCheckSuccess() { CloseableHttpResponse response = null; try { // 通過HttpClientBuilder創建CloseableHttpClient httpClient = HttpClientFactory.createHttpClient(); request = initCheckRequest(); response = httpClient.execute(request); if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { return true; } } finally { // 釋放連接 if(request != null) { request.releaseConnection(); } } return false; } //構造請求參數 private static HttpPost initCheckRequest() throws IOException { HttpPost request = new HttpPost(callBackUrl); request.setHeader("contentType", ContentTypeEnum.JSON.getDesc()); Listparams = new ArrayList<>(); params.add(new BasicNameValuePair("developer_id", "111")); params.add(new BasicNameValuePair("sign", "sign")); HttpEntity postParams = new UrlEncodedFormEntity(params); request.setEntity(postParams); return request; }
根據釋放連接處代碼和抓包分析來看,request.releaseConnection(); 每次是發TCP RST包來關閉連接
解決方案既然是釋放連接不對,則修改代碼為如下:
finally { if(response != null) { try { EntityUtils.consume(response.getEntity()); response.close(); } catch (IOException e) { logger.error("close http error", e); } } }
正確方式為:
關閉內容流后再關閉響應本身。
如果不關閉IO流,直接response.close(); 則結果是連接不能復用,直接通過4次揮手斷開TCP連接。
連接池釋放連接的時候,并不會直接對TCP連接的狀態有任何改變,只是維護了兩個Set,leased和avaliabled,leased代表被占用的連接集合,avaliabled代表可用的連接的集合,釋放連接的時候僅僅是將連接從leased中remove掉了,并把連接放到avaliabled集合中
本人blog:https://my.oschina.net/hebaod...
參考TCP RST相關
http://www.cnblogs.com/JohnAB...
http://blog.csdn.net/erlib/ar...
http://lovestblog.cn/blog/201...
https://my.oschina.net/costax...
HttpClient相關
https://www.cnblogs.com/likai...
http://liangbizhi.github.io/h...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70649.html
摘要:滑動窗口滑動窗口毫無疑問是用來加速數據傳輸的。處理程序會在自己認為的異常時刻發送包。序列號問題是與滑動窗口對應的,偽造的包里需要填序列號,如果序列號的值不在之前向發送時的滑動窗口內,是會主動丟棄的。 看Apache HttpClient的源碼時,發現abortRequest的時候,調用到socket時代碼如下: public void shutdown() throws IOExcep...
摘要:服務器出現異常最長出現的狀況是服務器保持了大量的狀態。此時主動關閉一方必須保持一個有效的狀態下維持狀態信息,以便可以重發。這就意味著,一個成功建立的連接,必須使得之前網絡中殘余的數據報都丟失了。,維持這些狀態給服務器端帶來巨大的負擔。 showImg(https://segmentfault.com/img/bV9DQk?w=732&h=563); showImg(https://se...
摘要:服務器出現異常最長出現的狀況是服務器保持了大量的狀態。此時主動關閉一方必須保持一個有效的狀態下維持狀態信息,以便可以重發。這就意味著,一個成功建立的連接,必須使得之前網絡中殘余的數據報都丟失了。,維持這些狀態給服務器端帶來巨大的負擔。 showImg(https://segmentfault.com/img/bV9DQk?w=732&h=563); showImg(https://se...
閱讀 3513·2021-10-08 10:04
閱讀 863·2019-08-30 15:54
閱讀 2180·2019-08-29 16:09
閱讀 1347·2019-08-29 15:41
閱讀 2272·2019-08-29 11:01
閱讀 1735·2019-08-26 13:51
閱讀 1026·2019-08-26 13:25
閱讀 1806·2019-08-26 13:24