当前位置:首页 > 技术分析 > 正文内容

Linux TCP RST情况

ruisui885个月前 (01-15)技术分析24

导致“Connection reset”的原因是服务器端因为某种原因关闭了Connection,而客户端依然在读写数据,此时服务器会返回复位标志“RST”,然后此时客户端就会提示“java.net.SocketException: Connection reset”。可能有同学对复位标志“RST”还不太了解,这里简单解释一下:


TCP建立连接时需要三次握手,在释放连接需要四次挥手;例如三次握手的过程如下:

第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;

第二次握手:服务器收到syn包,并会确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

可以看到握手时会在客户端和服务器之间传递一些TCP头信息,比如ACK标志、SYN标志以及挥手时的FIN标志等。

除了以上这些常见的标志头信息,还有另外一些标志头信息,比如推标志PSH、复位标志RST等。其中复位标志RST的作用就是“复位相应的TCP连接”。

TCP连接和释放时还有许多细节,比如半连接状态、半关闭状态等。详情请参考这方面的巨著《TCP/IP详解》和《UNIX网络编程》。

前面说到出现“Connection reset”的原因是服务器关闭了Connection[调用了Socket.close()方法]。大家可能有疑问了:服务器关闭了Connection为什么会返回“RST”而不是返回“FIN”标志。原因在于Socket.close()方法的语义和TCP的“FIN”标志语义不一样:发送TCP的“FIN”标志表示我不再发送数据了,而Socket.close()表示我不在发送也不接受数据了。问题就出在“我不接受数据” 上,如果此时客户端还往服务器发送数据,服务器内核接收到数据,但是发现此时Socket已经close了,则会返回“RST”标志给客户端。当然,此时客户端就会提示:“Connection reset”。详细说明可以参考oracle的有关文档:http://docs.oracle.com/javase/1.5.0/docs/guide/net/articles/connection_release.html。

另一个可能导致的“Connection reset”的原因是服务器设置了Socket.setLinger (true, 0)。但我检查过线上的tomcat配置,是没有使用该设置的,而且线上的服务器都使用了nginx进行反向代理,所以并不是该原因导致的。关于该原因上面的oracle文档也谈到了并给出了解释。

此外啰嗦一下,另外还有一种比较常见的错误“Connection reset by peer”,该错误和“Connection reset”是有区别的:

服务器返回了“RST”时,如果此时客户端正在从Socket套接字的输出流中读数据则会提示Connection reset”;

服务器返回了“RST”时,如果此时客户端正在往Socket套接字的输入流中写数据则会提示“Connection reset by peer”。

“Connection reset by peer”如下图所示:

前面谈到了导致“Connection reset”的原因,而具体的解决方案有如下几种:

出错了重试;

客户端和服务器统一使用TCP长连接;

客户端和服务器统一使用TCP短连接。

首先是出错了重试:这种方案可以简单防止“Connection reset”错误,然后如果服务不是“幂等”的则不能使用该方法;比如提交订单操作就不是幂等的,如果使用重试则可能造成重复提单。

然后是客户端和服务器统一使用TCP长连接:客户端使用TCP长连接很容易配置(直接设置HttpClient就好),而服务器配置长连接就比较麻烦了,就拿tomcat来说,需要设置tomcat的maxKeepAliveRequests、connectionTimeout等参数。另外如果使用了nginx进行反向代理或负载均衡,此时也需要配置nginx以支持长连接(nginx默认是对客户端使用长连接,对服务器使用短连接)。

使用长连接可以避免每次建立TCP连接的三次握手而节约一定的时间,但是我这边由于是内网,客户端和服务器的3次握手很快,大约只需1ms。ping一下大约0.93ms(一次往返);三次握手也是一次往返(第三次握手不用返回)。根据80/20原理,1ms可以忽略不计;又考虑到长连接的扩展性不如短连接好、修改nginx和tomcat的配置代价很大(所有后台服务都需要修改);所以这里并没有使用长连接。

正常情况tcp四层握手关闭连接,rst基本都是异常情况,整理如下:

0.使用 ping 可以看到丢包情况

1. **

2. 对方端口未打开,发生在连接建立

如果对方sync_backlog满了的话,sync简单被丢弃,表现为超时,而不会rst[/yiji]

3. close Socket 是recv buffer 不为空

例如,客户端发了两个请求,服务器只从buffer 读取第一个请求处理完就关闭连接,tcp层认为数据没有正确提交到应用,使用rst关闭连接。

4. 移动链路

移动网络下,国内是有5分钟后就回收信令,也就是IM产品,如果心跳>5分钟后服务器再给客户端发消息,就会收到rst。也要查移动网络下IM 保持<5min 心跳。

5. 负载等设备

负载设备需要维护连接转发策略,长时间无流量,连接也会被清除,而且很多都不告诉两层机器,新的包过来时才通告rst。

Apple push 服务也有这个问题,而且是不可预期的偶发性连接被rst;rst 前第一个消息write 是成功的,而第二条写才会告诉你连接被重置,

曾经被它折腾没辙,因此打开每2秒一次tcp keepalive,固定5分钟tcp连接回收,而且发现连接出错时,重发之前10s内消息。

6. SO_LINGER 应用强制使用rst 关闭

该选项会直接丢弃未发送完毕的send buffer,可能造成业务错误,慎用; 当然内网服务器http client 在收到应该时主动关闭,使用该选项,会节省资源。

好像曾经测试过haproxy 某种配置下,会使用rst关闭连接,少了网络交互而且没有TIME_WAIT 问题

7. 超过超时重传次数、网络暂时不可达

8. TIME_WAIT 状态

tw_recycle = 1 时,sync timestamps 比上次小时,会被rst[/yiji]

9. 设置 connect_timeout

应用设置了连接超时,sync 未完成时超时了,会发送rst终止连接。[/yiji]

10. 非正常包

连接已经关闭,seq 不正确等

11. keepalive 超时

公网服务tcp keepalive 最好别打开;移动网络下会增加网络负担,且容易掉线;非移动网络核心ISP设备也不一定都支持keepalive,曾经也发现过广州那边有个核心节点就不支持。

12. 数据错误,不是按照既定***发送数据

13.在一个已关闭的socket上接收数据

14.服务器关闭或异常终止了连接由于网络问题

客户端没有收到服务器的关闭请求,这称为TCP半打开连接。就算重启服务器,也没有连接信息。如果客户端向提其写入数据,对方就会回应一个RST报文段。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/307.html

标签: .rst
分享给朋友:

“Linux TCP RST情况” 的相关文章

代码管理-9-gitlab的使用和设置

gitlab使用1、外观设置完成后保存,返回登录页面查看关于注册,有些公司是不允许打开的,,有些人数非常多的公司就需要打开注册的功能,让人员自己注册,我们来给他特定的权限就可以,毕竟人非常多的时候还由我们来给她们注册就非常不现实了,工作量会很大2、自动注册3、组&用户&项目创建组设置组名称、描述等创...

HTML5+眼球追踪?黑科技颠覆传统手机体验

今天,iH5工具推出一个新的神秘功能——眼动追踪,可以通过摄像头捕捉观众眼球活动!为了给大家具体演示该功能的使用,我做了一个案例,供大家参考。实际效果如下:案例比较简单,就是通过眼动功能获取视觉焦点位置,剔除用户看中的牌。现在,舞台的属性中多了一个“启用眼动”的选项,另外,还多了一个“启用摄像头”的...

vue v-html动态生成的html怎么加样式/事件

1、动态生成的html,样式不生效//html 布局 <view v-html="html"> {{html}} </view> //动态生成的元素 <view class="btngo" @tap="handleLink...

Alpine.js 如何火起来的!比 React/Vue 如何?

大家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!前言前端 JavaScript 框架的创新是这个时代最伟大的技术文化现象之一。Alpine 发音为 /??lpa?n/,中文为阿尔卑斯山、...

面试官:给我说说什么是同步异步?

今天是刘小爱自学Java的第95天。感谢你的观看,谢谢你。话不多说,开始今天的学习:一、同步、异步请求浏览器发送请求给服务器,其有同步请求和异步请求两种方式。1同步请求什么叫同步请求呢?就是在发送一个请求之后,需要等待服务器响应返回,才能够发送下一个请求。之前学的请求是通过浏览器地址栏发送请求,这种...

甘肃省2023年普通高校毕业生基层服务项目考试成绩今日公布

甘肃省2023年普通高校毕业生基层服务项目考试成绩今日公布每日甘肃网7月12日讯据兰州日报报道 近日,记者从甘肃省人力资源考试中心了解到,甘肃省2023年普通高校毕业生基层服务项目(三支一扶、特岗计划、西部计划)考试成绩于7月12日9:00开通查询。考生可登录“甘肃人事考试网”,点击“成绩查询”栏目...