分析过程:根据TCP建立连接和断开连接的过程,如下图:

close wait状态一般是在服务端出现的。执行:ss -tnp | grep CLOSE-WAIT | wc -l命令可查看有多少close wait连接状态;执行:ss -tnp | grep CLOSE-WAIT | more,根据第三、四列可以看出,由谁向谁发起socket连接(客户端发起请求的端口是随机的,服务端提供服务的端口比较有规律)。根据TCP断开连接的状态变换过程,基本可以判断close wait堆积是因为客户端发出FIN包,服务端回了ACK包,但是服务端没发出FIN包导致。

分析代码后发现,客户端有调用关闭socket方法去主动关闭socket连接,但是服务端没有调用关闭socket方法发送FIN包结束连接,导致服务端大量close wait堆积。

解决方法:服务端加上调用关闭socket方法发送FIN给客户端。上新版本后,连续几天到服务端执行ss -tnp | grep CLOSE-WAIT | wc -l命令,没发现有大量close wait了。

另附如下tcp连接相关内容:

TCP建立连接(三次握手)都是由客户端发起的,但是断开连接视情况而定。一般由客户端主动断开连接比较好,因为由服务端发起断开连接,服务器会产生time-wait状态的连接,而time wait占用的资源不会被内核释放。SSH、数据库等断开连接由客户端主动发起,如果超时了,断开连接可能由服务端发起。

HTTP(S)断开连接有时由服务端主动发起,如下情况:

1、客户端请求头带content-length时,响应体body长度可知,接收完数据后,客户端主动断开连接

2、响应头中的Transfer-encoding为chunked传输,body会被分成多个块,每块的开始会标识出当前块的长度,body就不需要通过content-length来指定了。也可以知道body的长度,客户端主动断开连接

3、响应头中的Transfer-encoding为非chunked传输,而且有content-length,则按照content-length来接收数据,接收完数据后,客户端主动断开连接

4、响应头中的Transfer-encoding非chunked且不带content-length,客户端无法知道要接收多少数据,直到服务端主动断开连接。

即 :如果客户端知道服务器传来的长度,客户端在接收完成后,会主动断开;如果不知道,客户端就一直接收数据,直到服务端断开连接。

在TCP的三次握手、数据传输以及四次挥手的过程中,给Client和Server定义了很多状态用于描述整个流程,结合上面的状态转换图来理解这些状态定义:

  • LISTEN(Server): 正在侦听来自Client的TCP端口的连接请求,服务端启动后处于LISTEN 状态用于监听不同客户端的TCP请求并建立连接
  • SYN-SENT(Client): 三次握手时,Client在发送SYN后处于等待建立连接的状态
  • SYN_RCVD(Server):三次握手时,当Server收到Client的SYN时,将ACK和SYN发送给 Client后到建立连接之前,Server处于SYN_RCVD状态
  • ESTABLISHED(Server And Client):三次握手成功以后,Client和Server处于数据传输的状态
  • FIN-WAIT-1(Client):四次挥手时,Client 端发送中断请求FIN到收到Server端的中断确认的过程
  • CLOSE_WAIT(Server):四次挥手时,Server接收到Client的FIN请求后回复ACK确认到发送FIN包的状态
  • FIN-WAIT-2(Client):四次挥手时,当Client接收到Server对于FIN的响应ACK后到收到 Server端的FIN包的状态
  • LAST_ACK(Server):四次挥手时,Server发送FIN请求关闭连接到关闭连接前的状态
  • TIME_WAIT(Client):四次挥手时,Client对于Server的FIN回复ACK到连接关闭前的状态,又称 2MSL 状态
  • CLOSE(Server And Client):Server和CLient关闭连接后的状态

客户端的状态转换流程如下:

大部分情况下:CLOSED -> SYN_SENT -> ESTABLISHED -> FIN_WAIT_1 -> FIN_WAIT_2 -> TIME_WAIT -> CLOSED

少数情况:CLOSED -> SYN_SENT -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED

服务端的状态转换流程如下:

大部分情况下:CLOSED -> LISTEN -> SYN_RCVD -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED

少数情况:CLOSED -> LISTEN -> SYN_RCVD -> ESTABLISHED -> FIN_WAIT_1 -> FIN_WAIT_2 -> TIME_WAIT -> CLOSED

为何服务器上存在CLOSE_WAIT?

  1. 在数据库连接过程中,客户端(或发起请求的应用)提交或回滚事务时,忘记关闭(即没发送FIN)与数据库的连接,导致数据库因为连接超时而主动关闭连接(即数据库主动发送FIN),此时,发起请求的应用服务器(客户端),就会出现大量CLOSE_WAIT状态。
  2. 例2,客户端发送了FIN,但是服务端忙于读或者写(处理未完成的客户端请求),没有及时发送FIN,此时可能会有少量的close wait。代码需要判断socket连接,一旦读到0,断开连接。

总之,被动关闭的一方(一般是服务端)要调用关闭 socket方法,才会发送FIN给主动关闭的一方(一般是客户端),自己的状态才会变LAST_ACK。

TCP close-wait 状态分析相关推荐

  1. Web基础与apache讲解

    Web基础与apache讲解 一.网站基础: 二.HTTP协议分析: 三.TCP数据包状态分析: 四.apache原理详解: 五.案例:搭建apache网站服务: 一.网站基础: 1.域名:域名是一个 ...

  2. c语言实现将字符串首尾*删除,java 编写函数将字符串的首尾空格删除。

    String 类有个方法去除字符串首位空格: str.trim(); 查看源代码: public String trim() { int len = value.length; int st = ; ...

  3. TCP/IP详解--TCP/IP中三次握手 四次握手状态分析

    TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...

  4. 通讯系统经验谈【一】TCP连接状态分析:SYNC_RECV,CLOSE_WAIT,TIME_WAIT

    摘自:http://maoyidao.iteye.com/blog/1744277 面试时看到应聘者简历中写精通网络,TCP编程,我常问一个问题,TCP建立连接需要几次握手?95%以上的应聘者都能答对 ...

  5. TCP/IP之TCP连接的建立与中止状态分析

    TCP连接的建立可以简单的称为三次握手,而连接的中止则可以叫做四次握手. 1.连接的建立: c端发起请求同步(用SYN段等于1的TCP报文),确认某个端口是否监听: s端应答(用ACK段等于1的TCP ...

  6. tcp port numbers reused出现原因_谈谈 TCP 的 TIME_WAIT

    由来 最近有同事在用 ab 进行服务压测,到 QPS 瓶颈后怀疑是起压机的问题,来跟我借测试机,于是我就趁机分析了一波起压机可能成为压测瓶颈的可能,除了网络 I/O.机器性能外,还考虑到了网络协议的问 ...

  7. 传输层两大协议:TCP与UDP详解(两者的联系与区别)

    一.TCP协议 1.TCP协议报文格式 TCP协议报文格式详解 2.TCP"三次握手"建立连接 位码即tcp标志位,有6种标示: SYN(synchronous建立联机) ACK( ...

  8. linux系统调用socket(TCP使用总结)

    概念:  三次握手. 四次挥手   socket :  tcp udp . 广播. 组播.   并发:         多线程实现       多进程实现   第三方库来解决高并发:       se ...

  9. LWIP应用开发|TCP状态机

    TCP状态机 1. TCP状态机 TCP状态机是TCP连接的变化过程.TCP在三次握手和四次挥手的过程,就是一个TCP的状态说明,由于TCP是一个面向连接的,可靠的传输,每一次的传输都会经历连接,传输 ...

  10. HTTP 协议入门 — (TCP/IP协议族、通信传输流、URI 与 URL 的区别、Cookie 状态管理、HTTP 支持的方法、状态码类别、HTTP 首部字段)

    TCP/IP协议族 在介绍 HTTP 协议之前,我们先对 TCP/IP 协议族有个大概的了解,TCP/IP 协议从上到下主要分为应用层.传输层.网络层和数据链路层,各层的主要功能如下表所示: 协议层 ...

最新文章

  1. python水仙花数_scratch与pythonc++的不同,你了解吗?
  2. python怎么画条形图-python使用Matplotlib画条形图
  3. mysql 升序 字段值为NULL 排在后面
  4. 解决webpack打包后-webkit-box-orient: vertical ;消失问题
  5. 4、Kafka常见问题
  6. 改名之后的 Java EE,现在有什么新进展?
  7. python-迭代器实现异步(在串行中)
  8. SpringBoot项目热部署配置
  9. AdRotator,广告轮播 #1 -- 透过XML档来作设定。
  10. Matlab 2016a 安装教程
  11. Eclipse 设置保护色
  12. /proc文件系统详解
  13. python正则表达式match方法_Python match()函数:匹配正则表达式
  14. 软件开发流程中的测试及测试方法简介
  15. STM32(3)——外部中断的使用
  16. BGP Confederation(BGP联邦)
  17. 校验导入的Excel文件标题行与要求的标题行是否一致
  18. 一、万信金融项目——项目介绍
  19. OpenWrt下使用docker安装icloudpd实现iPhone照片备份私有云盘nas
  20. JS获取当前时间戳与时间戳转日期时间格式

热门文章

  1. matlab的替代品,matlab的开源替代品--octave
  2. EKS使用AWS EFS CSI
  3. vue导出word模版文档
  4. 微信公众上传头像和分享
  5. linux自动登录帐号密码,设定Linux自动登陆
  6. Cocos2dx3.2学习准备(一):C++11新特性
  7. windows xp系统安装教程
  8. 2017年中国智能卡行业发展现状分析及市场发展前景预测
  9. 有奖互动 | 感恩节福利放送中
  10. 从2009到2020,世界编程语言排行榜分析