加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

TCP的状态转换及生产问题实操

发布时间:2019-02-27 08:57:31 所属栏目:教程 来源:itworld123
导读:前文介绍了TCP协议主要的流程,包括建立连接、传输数据和断开连接。如果大家认真阅读了附图,应该可以看到在各个流程中套接字的状态是在不断变化的,不同的状态标识了套集字所处的阶段。 如图1是TCP一个完整的状态转换图,图中包含了套接字的所有状态,以

当然,也可以通过shell脚本实现复杂的查询,比如下面用于统计ESTABLISHED状态的数量。

  1. netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 

netstat命令功能非常强大,由于篇幅问题,本文只能抛砖引玉,更多功能可以man一下看看,这里就不过多解释。

三、实际生产环境的意义

前面啰嗦了一大堆,我们回到正题,了解这些状态到底有什么用呢?我们知道Linux操作系统对文件句柄的总量是有限制的,套接字也属于文件句柄,因此也是有限制的。了解套接字的状态有助于我们了解服务器是否有隐患或者性能瓶颈。

说到这,可能有的同学还是不明白,我们举个简单的例子。假设一台服务器最多有6万个句柄,如果由于某种业务场景,在服务器端出现大量的TIME_WAIT,此时这些套接字是无法马上释放,也就是无法马上被重复使用,但仍然占用6万句柄的名额。这块,随着时间的推移,可能会耗尽所有句柄,从而导致有新的连接请求是服务器端无法响应的问题。

为了让大家更形象的理解这些状态在实际生产中的意义,我们举几个实际生产中遇到问题的例子。

1. 服务器端大量TIME_WAIT

(1) 现象描述

某对象存储服务,在监控系统发现有大量的TIME_WAIT。经确认该服务器是一台新上架接入的服务器。经反复确认,具备相同功能的同集群的其它服务器工作都正常,并不存在大量TIME_WAIT的情况。

(2) 问题分析

结合协议我们知道主动关闭方会处于该状态,而且TIME_WAIT状态下的TCP连接会等待2*MSL。因此我们查看系统配置cat /proc/sys/net/ipv4/tcp_fin_timeout,发现是默认值。因此,确定是等待时间太长,导致套接字无法被利用所致。

(3) 问题解决

通过调整内核参数解决,打开文件/etc/sysctl.conf,编辑文件,加入以下内容:

  1. net.ipv4.tcp_syncookies = 1 
  2. net.ipv4.tcp_tw_reuse = 1 
  3. net.ipv4.tcp_tw_recycle = 1 
  4. net.ipv4.tcp_fin_timeout = 30 

然后执行/sbin/sysctl -p让参数生效。

上述内容的含义具体如下:

  • net.ipv4.tcp_syncookies = 1表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
  • net.ipv4.tcp_tw_reuse = 1表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
  • net.ipv4.tcp_tw_recycle = 1表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
  • net.ipv4.tcp_fin_timeout修改系統默认的TIMEOUT时间

2. 服务器端大量ESTABLISHED

(1) 问题描述

某Tomcat服务器出现大量ESTABLISHED连接。

(2) 问题分析

根据协议状态转换情况,初步推断是tomcat服务器回收session时出了问题,这个一般都跟服务器的Timeout设置有联系。

查看tomcat的配置文件 server.xml

  1. <Connector port="8080" protocol="HTTP/1.1" 
  2.  connectionTimeout="20000" 
  3.  redirectPort="8443" URIEncoding="UTF-8" /> 
  4. ***** 

我们重点关注一下connectionTimeout,这个配置导致建立一个socket连接后,如果一直没有收到客户端的FIN,也没有数据过来,那么此连接也必须等到10s后,才能被超时释放。由于服务器并发量大,而该超时时间有长,导致连接释放严重滞后,因此出现大量的ESTABLISHED连接。

(3) 问题解决

分析上述问题后,我们有针对性的作出如下修改。

  1. connectionTimeout="20000" 改为 connectionTimeout="100" 
  2. acceptCount="100"改为acceptCount="5000" 

修改后问题解决。

实际的例子还很多,但万变不离其宗,需要我们熟悉TCP协议和状态转换,这样在实际生产中遇到问题就可以有理有据的进行分析,然后轻松解决。

【编辑推荐】

  1. 网络七层协议的通俗理解
  2. TCP三次握手,四次挥手,你真的懂吗?
  3. 从TCP到Socket,彻底理解网络编程是怎么回事
  4. 如何理解总线通讯协议的多层模型
  5. 物联网协议那么多:究竟LoRa、Cat-M和NB-IoT哪一个是你的菜?
【责任编辑:赵宁宁 TEL:(010)68476606】
点赞 0

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读