摘要:问题现象在与第三方系统通过交互数据的过程中,抓包发现每次连接都是异常关闭,报文如下可以看到,由我方发起次握手建立连接,然后发送请求,对方响应数据,我方后直接发包图中蓝色阴影部分,将连接异常关闭,不仅没有复用连接,且不是通过次挥手来关闭连接。
问题现象
在与第三方系统通过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...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/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...
阅读 3456·2021-10-08 10:04
阅读 826·2019-08-30 15:54
阅读 2136·2019-08-29 16:09
阅读 1322·2019-08-29 15:41
阅读 2241·2019-08-29 11:01
阅读 1697·2019-08-26 13:51
阅读 999·2019-08-26 13:25
阅读 1774·2019-08-26 13:24