close_wait问题的示例分析

这篇文章给大家介绍close_wait问题的示例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

成都创新互联公司长期为成百上千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为兴国企业提供专业的成都网站建设、网站建设,兴国网站改版等技术服务。拥有十余年丰富建站经验和众多成功案例,为您定制开发。

前言

有一次商户反映访问我们服务出现问题,很多超时现象,我们登陆服务器查询问题时,发现-bash: fork: retry: 资源暂时不可用,并检查了系统的tcp连接的情况,发现closewait非常多。

问题描述

现象有

  1. 商户连接不到我们的服务

  2. xshell登陆服务器报 bash: fork: retry: 资源暂时不可用

  3. 查看系统tcp连接情况,发现 closewait非常多

  4. 应用进程存活,日志正常打印。

我准备从外到内分析问题。网络-》系统-》应用。

1. 网络

商户访问不到我们服务,这牵扯到的网络测问题非常多。我联系了网络部同事,询问这个时间段是否有商户访问我司网络出现问题,网络部确定没有问题。

2. 系统

2.1 资源暂时不可用

出现 bash: fork: retry: 资源暂时不可用。我查询资料,结果如下:

可能是因为资源限制,要么是系统自己的,要么是系统的用户下。资源限制可用通过 ulimit -a 查看。ulimit -u 会打印最大用户进程数。如果超过了最大进程数,fork不能创建新的进程,就会打印上面的错误。也有可能是因为交换内存资源问题。

我就使用ulimit -u查看最大用户进程数是1024。

2.2 tcp closewait很多

tcp closewait 是在关闭连接时,服务端的一个中间状态。这里先介绍下tcp连接释放。

2.2.1 tcp 释放连接过程

close_wait问题的示例分析

tpc_close__.jpg

tpc建立连接完成,数据传输结束后,通信的双方都可以释放连接。现在A和B都处于建立连接的状态。A的应用进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。A把连接释放报文段首部FIN置1,其序号seq=u,它等于前面已传送过的数据最后一个字节的序号加1。这时A处于FIN-WAIT-1(终止等待1),等待B确认。注意,TPC规定,fin报文即使不携带数据,也要消耗一个序号。

B收到连接释放报文段后即发出确认,而这个报文段自己的序号是v,等于B前面已经传送过的数据最后一个字节的序号加1,然后B就进入CLOSE-WAIT状态。TCP服务器进程就应通知高层应用进程,因而从A到B这个方向的连接就释放了,这是TCP处于半关闭状态,即A已经没有数据要发送了,但是B若发送数据,A仍要接收。也就是说,从B到A这个方向的连接并未关闭。这个状态可能会持续一些时间

A收到来自B的确认后,就进入了FIN-WAIT-2(终止等待2),等待B发出的连接释放报文段。

若B已经没有要向A发送的数据,其应用程序就通知TCP释放连接。这时B发出的连接释放报文段必须使FIN=1。现假设B的序号是w(在半关闭状态B有可能发送了一些数据)。B还必须重复上次已发送过的确认号ack=u+1。这时B就进入LAST-ACK(最后确认状态),等待A的确认。

A在收到B的连接释放报文后段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack=w+1,而自己的序号是seq=u+1(根据TCP标准,前面发送过的FIN报文段要消耗一个序号)。然后进入TIME-WAIT(时间等待状态)。请注意新增的TCP连接还没有释放掉。必须经过时间等待计数器设置的时间2MSL后,A才进入CLOSED状态。时间MSL叫做最长报文段寿命,RFC793建议设为2分钟。但这完全是从工程上考虑,对于现在的网络,MSL=2分钟可能太长了。因此TCP允许不同的实现可根据具体情况使用最小的MSL值。因此从A进入TIME-WAIT状态后,要经过4分钟才能进入到CLOSED的状态,才能开始建立下一个新的连接。当A撤销相应的传输控制块TCB后,就结束了这次TCP连接。

B只要接收到了A发出的确认,就进入CLOSED状态。同样,B在撤销相应的传输控制块TCB后,就结束了这次TCP连接。我们注意到,B结束TCP连接的时间要比A早一些。

上述连接释放是四次握手,但也可以看作是两个两次握手。

2.2.2 存在大量 close-wait的原因

CLOSE-WAIT的状态是B已经知道A不在向B发送数据,因此B在合适的时间段内可以让其应用程序通知TCP释放连接。那现在的问题是B的应用程序为什么迟迟不通知TCP释放连接,是应用程序挂了,还是应用程序的资源达到临界值,不能够做出 通知TCP释放连接这个操作。回想到刚才提到了系统资源不可用,会不会是因为B的应用程序想通知TCP释放连接,但是由于没有系统资源,而无法执行这个操作。

我们查看了服务器的应用部署情况,发现该服务器部署很多应用,每个应用响应tcp请求的线程池都是100+,在业务高峰期,很有可能达到最大用户进程数1024,从而引发这一系列的问题。

应用

应用测设置的响应tcp请求的线程池都是100+,并且当时服务器部署应用很多。

解决方案

  • 增大系统用户进程数限制

  • 迁移部分不重要的应用到其他服务器,降低服务器压力

思考

  1. 为什么之前没有暴漏出来。业务高峰期,为什么会将系统资源吃满。实际的系统吞吐量和tps是多少。是不是我们业务处理能力较之前有降低。

  2. 质量监控体系中缺少压测环节。

后记

随着5g的普及,网络的速度得到巨大的提升,掌握网络知识已经是必不可少的技能之一。

关于close_wait问题的示例分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


文章名称:close_wait问题的示例分析
文章来源:http://scjbc.cn/article/iipoei.html

其他资讯