摘要:?jiǎn)栴}現(xiàn)象在與第三方系統(tǒng)通過(guò)交互數(shù)據(jù)的過(guò)程中,抓包發(fā)現(xiàn)每次連接都是異常關(guān)閉,報(bào)文如下可以看到,由我方發(fā)起次握手建立連接,然后發(fā)送請(qǐng)求,對(duì)方響應(yīng)數(shù)據(jù),我方后直接發(fā)包圖中藍(lán)色陰影部分,將連接異常關(guān)閉,不僅沒(méi)有復(fù)用連接,且不是通過(guò)次揮手來(lái)關(guān)閉連接。
問(wèn)題現(xiàn)象
在與第三方系統(tǒng)通過(guò)http交互數(shù)據(jù)的過(guò)程中,抓包發(fā)現(xiàn)每次TCP連接都是異常關(guān)閉,報(bào)文如下:
可以看到,由我方發(fā)起3次握手建立連接,然后發(fā)送http請(qǐng)求,對(duì)方響應(yīng)數(shù)據(jù),我方ACK后直接發(fā)RST包(圖中藍(lán)色陰影部分),將連接異常關(guān)閉,不僅沒(méi)有復(fù)用連接,且不是通過(guò)4次揮手來(lái)關(guān)閉連接。
關(guān)于RST包參考:http://blog.csdn.net/erlib/ar...
問(wèn)題原因HttpClient 4.5.2 釋放連接API使用方式不正確
問(wèn)題代碼如下(已簡(jiǎn)化):
private boolean isCheckSuccess() { CloseableHttpResponse response = null; try { // 通過(guò)HttpClientBuilder創(chuàng)建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; } //構(gòu)造請(qǐng)求參數(shù) 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; }
根據(jù)釋放連接處代碼和抓包分析來(lái)看,request.releaseConnection(); 每次是發(fā)TCP RST包來(lái)關(guān)閉連接
解決方案既然是釋放連接不對(duì),則修改代碼為如下:
finally { if(response != null) { try { EntityUtils.consume(response.getEntity()); response.close(); } catch (IOException e) { logger.error("close http error", e); } } }
正確方式為:
關(guān)閉內(nèi)容流后再關(guān)閉響應(yīng)本身。
如果不關(guān)閉IO流,直接response.close(); 則結(jié)果是連接不能復(fù)用,直接通過(guò)4次揮手?jǐn)嚅_(kāi)TCP連接。
連接池釋放連接的時(shí)候,并不會(huì)直接對(duì)TCP連接的狀態(tài)有任何改變,只是維護(hù)了兩個(gè)Set,leased和avaliabled,leased代表被占用的連接集合,avaliabled代表可用的連接的集合,釋放連接的時(shí)候僅僅是將連接從leased中remove掉了,并把連接放到avaliabled集合中
本人blog:https://my.oschina.net/hebaod...
參考TCP RST相關(guān)
http://www.cnblogs.com/JohnAB...
http://blog.csdn.net/erlib/ar...
http://lovestblog.cn/blog/201...
https://my.oschina.net/costax...
HttpClient相關(guān)
https://www.cnblogs.com/likai...
http://liangbizhi.github.io/h...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70649.html
摘要:滑動(dòng)窗口滑動(dòng)窗口毫無(wú)疑問(wèn)是用來(lái)加速數(shù)據(jù)傳輸?shù)?。處理程序?huì)在自己認(rèn)為的異常時(shí)刻發(fā)送包。序列號(hào)問(wèn)題是與滑動(dòng)窗口對(duì)應(yīng)的,偽造的包里需要填序列號(hào),如果序列號(hào)的值不在之前向發(fā)送時(shí)的滑動(dòng)窗口內(nèi),是會(huì)主動(dòng)丟棄的。 看Apache HttpClient的源碼時(shí),發(fā)現(xiàn)abortRequest的時(shí)候,調(diào)用到socket時(shí)代碼如下: public void shutdown() throws IOExcep...
摘要:服務(wù)器出現(xiàn)異常最長(zhǎng)出現(xiàn)的狀況是服務(wù)器保持了大量的狀態(tài)。此時(shí)主動(dòng)關(guān)閉一方必須保持一個(gè)有效的狀態(tài)下維持狀態(tài)信息,以便可以重發(fā)。這就意味著,一個(gè)成功建立的連接,必須使得之前網(wǎng)絡(luò)中殘余的數(shù)據(jù)報(bào)都丟失了。,維持這些狀態(tài)給服務(wù)器端帶來(lái)巨大的負(fù)擔(dān)。 showImg(https://segmentfault.com/img/bV9DQk?w=732&h=563); showImg(https://se...
摘要:服務(wù)器出現(xiàn)異常最長(zhǎng)出現(xiàn)的狀況是服務(wù)器保持了大量的狀態(tài)。此時(shí)主動(dòng)關(guān)閉一方必須保持一個(gè)有效的狀態(tài)下維持狀態(tài)信息,以便可以重發(fā)。這就意味著,一個(gè)成功建立的連接,必須使得之前網(wǎng)絡(luò)中殘余的數(shù)據(jù)報(bào)都丟失了。,維持這些狀態(tài)給服務(wù)器端帶來(lái)巨大的負(fù)擔(dān)。 showImg(https://segmentfault.com/img/bV9DQk?w=732&h=563); showImg(https://se...
摘要:我們知道通過(guò)三次握手建立可靠連接,通過(guò)四次揮手?jǐn)嚅_(kāi)連接,連接是比較昂貴的資源。從上分析,安全可靠的斷開(kāi)連接至少需要四次,再多一次的意義不大。連接的異常斷開(kāi)以上都是在理想的情況下發(fā)生的,理想狀態(tài)下,一個(gè)連接可以被長(zhǎng)期保持。 我們知道TCP通過(guò)三次握手建立可靠連接,通過(guò)四次揮手?jǐn)嚅_(kāi)連接,TCP連接是比較昂貴的資源。為什么TCP需要通過(guò)三次握手才能建立可靠的連接??jī)纱尾恍忻??斷開(kāi)連接為什么需...
閱讀 3527·2021-10-08 10:04
閱讀 872·2019-08-30 15:54
閱讀 2189·2019-08-29 16:09
閱讀 1354·2019-08-29 15:41
閱讀 2285·2019-08-29 11:01
閱讀 1743·2019-08-26 13:51
閱讀 1035·2019-08-26 13:25
閱讀 1834·2019-08-26 13:24