我是如何确认线上CLOSE_WAIT产生的原因及如何解决的。
1、阐述
内部架构:Tomcat应用程序---> nginx ---> 其他Tomcat应用程序,内部Tomcat应用通过nginx调用其他应用。
HTTP插件:HttpClient 4.2.3
关闭连接的代码:httpClient.getConnectionManager().closeIdleConnections(5, TimeUnit.SECONDS);
2、说明
要说明的是CLOSE_WAIT产生的原因和服务器、nginx、其他配置无关,是HttpClient的getConnectionManager引起的。
3、排查思路
这个问题已经困扰我很久了,查看过网上的很多办法,也试过很多方法。
比如:修改服务器内核、修改nginx配置文件、更改nginx版本,都是没有用的,还是上面那句话和服务器、nginx无关。
最后决定自己分析请求,查找真正的根本原因,以下为排查的最终步骤
4、问题排查
首先确认CLOSE_WAIT产生的链接,链接的IP和端口

由上图看出是本机链接nginx 81端口造成的CLOSE_WAIT
抓包分析其中一个CLOSE_WAIT所用的本机端口:

抓包分析正常关闭的请求:

分析不正常端口41584,晚上22点01分02秒请求连接,22点01分02秒传输数据结束,22点02分07秒,nginx发送关闭连接的包,Tomcat同意关闭,问题就出现在这里,在Nginx请求关闭连接后,Tomcat并没有回复同样关闭连接的包,没有完成四次握手,故产生了CLOSE_WAIT。
分析所有正常连接发现没有产生CLOSE_WAIT的端口都是Tomcat主动关闭的,产生CLOSE_WAIT的都是nginx主动关闭,Tomcat被动关闭的。
再次分析所有的不正常端口

发现Tomcat周期性的向Nginx发送关闭连接的请求,但是Nginx回复Reset包,说白了就是Tomcat请求关闭连接,但是Nginx说我没有这个链接(已经在前面主动关闭),所有CLOSE_WAIT会一直存在,直至两个小时以后系统强制关闭。至于为什么会周期性的一起并发的关闭的连接,而不是一个一个关闭,或者为什么在收到Nginx关闭连接请求,Tomcat不关闭,看上述Java代码:httpClient.getConnectionManager().closeIdleConnections(5, TimeUnit.SECONDS);
这段代码表示调用httpClient的getConnectionManager,然后利用closeIdleConnections进行关闭空闲连接,5代表是五秒(不知道解释的对不对)。
网上查找getConnectionManager,说是httpclient的链接池管理工具。就是把请求都扔里面,然后Manager帮你做相关处理。
但是上述代码写的是5秒之内连接空闲就会连接,httpclient又是一个很成熟的技术,于是没有怀疑这个的问题(我不是开发,代码层我无法分析)。
继续分析其他正常关闭的包,发现并不是所有正常关闭的连接都是五秒关闭的,而产生CLOSE_WAIT的,一般请求关闭都是超过65秒的(65是nginx keepalive timeout的值),为了确认问题的根源,我把nginx的keepalive timeout设置为240秒(Nginx主动关闭连接后,最长Tomcat第一次发送关闭连接的包据数据传输完毕的时间间隔为3分28秒),实时查看CLOSE的增长变得缓慢,改为360秒,几乎不怎么增长,但是还有增长,索性改为0,过了一个多小时,只会下降,不会增多,所以断定是HTTPCLIENT出现的问题。
5、继续分析
查看httpclient官方文档:http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ClientConnectionManager.html

上面说在给定的时间内(上述代码的五秒)链接没有被使用,就会在池中关闭连接。同时也会关闭过期的连接。
看解释说只要连接5秒没有被使用,就会关闭连接,不会大于65秒的,至此又回到诧异懵逼中。。。
再次回想连接池中周期性发送FIN包,让我判断没有在五秒内关闭连接只有两种可能:一、配置没有生效,二、HTTPCLIENT空闲连接检测机制。
把自己的想法说给开发人员说后,决定修改代码,换用另一种关闭的方式(没有时间考虑上面的两个想法):将所有完成请求通过httpclient的releaseConnection和SHUTDOWN进行关闭,修改完成并在测试环境部署(测试环境也同样有CLOSE_WAIT),运行至今并无产生任何CLOSE_WAIT。
6、总结
CLOSE_WAIT产生的原因是由代码引起的,目前能确认的是HTTPCLIENT的getConnectionManager的连接池引起的,但是为什么设置的5秒没有生效,空闲连接的检测机制是什么,这些还无法得知。
我是如何确认线上CLOSE_WAIT产生的原因及如何解决的。的更多相关文章
- 一次线上http接口调用不通相关的解决过程
2016-05-25 08:58:34 昨天线上小白系统因为调用外部http接口,超时不释放,导致页面反应很慢,时间一长,报502错误. 上网查了下,502错误是因为服务对于客户的请求没有得到及时的反 ...
- 线上Redis偶发性链接失败排查记
问题过程 输入法业务于12月12日上线了词库接受业务,对部分用户根据用户uuid判断进行回传,在12月17日早上8点多开始出现大量的php报错(Redis went away),报错导致了大量的链接积 ...
- 线上bug分析
昨天下午大神把组内几十号人召集在一起开Online bug分析大会,主要是针对近期线上事故从事故原因和解决方案两个维度来分析. 对金融软件来说,每一次的线上事故都有可能给公司带来重大的损失,少扣了用户 ...
- 线上一次大量 CLOSE_WAIT 复盘
https://mp.weixin.qq.com/s/PfM3hEsDa3CMLbbKqis-og 线上一次大量 CLOSE_WAIT 复盘 原创 ms2008 poslua 2019-07-05 最 ...
- [Nginx笔记]关于线上环境CLOSE_WAIT和TIME_WAIT过高
运维的同学和Team里面的一个同学分别遇到过Nginx在线上环境使用中会遇到TIME_WAIT过高或者CLOSE_WAIT过高的状态 先从原因分析一下为什么,问题就迎刃而解了. 首先是TIME_WAI ...
- 分布式存储 FastDFS-5.0.5线上搭建
前言: 由于公司项目需要,最近开始学习一下分布式存储相关知识,确定使用FastDFS这个开源工具.学习之初,自己利用VMware虚拟机搭建了一个5台机器的集群,摸清了安装过程中可能出现的问 ...
- 线上Linux服务器运维安全策略经验分享
线上Linux服务器运维安全策略经验分享 https://mp.weixin.qq.com/s?__biz=MjM5NTU2MTQwNA==&mid=402022683&idx=1&a ...
- 【阿里云产品公测】OTS使用之简单线上产品实践基于PythonSDK
阿里云用户:morenocjm 实践是检验真理的唯一标准,学习技术需要通过实践过程中的不断尝试,才能够快速掌握要领.OTS是构建在阿里云飞天分布式系统之上的NoSQL数据库服务,提供海量结构化数据的存 ...
- 【微学堂】线上Linux服务器运维安全策略经验分享
技术转载:https://mp.weixin.qq.com/s?__biz=MjM5NTU2MTQwNA==&mid=402022683&idx=1&sn=6d403ab4 ...
随机推荐
- 关于String中的不变模式
不变模式 不变模式就是为了尽可能的去除并行中的同步操作,提高并行程序的性能,可以使用一种不可改变的对象,依靠对象的不变性,可以确保其在没有同步操作的多线程环境中依然始终保持内部状态的一致性和正确性.并 ...
- Python入门 - 容器类型
python的容器有四种:列表List,元祖Tuple,字典Dictionary和集合Set. 一.列表List a = [1, 2, 3, 'a', 'b', 'c'] b = 1.5 a.appe ...
- TFS2017持续发布中调用PowerShell启停远程应用程序
目前团队项目中有多个Web.服务以及与大数据平台对接接口等应用,每次的发布和部署采用手工的方式进行.停止应用程序,拷贝发布包,启动应用程序,不停的循环着,并且时不时地会出现一些人为错误性问题.这种模式 ...
- docker学习(一)
docker的安装 (一)环境要求: 容器需要管理工具.runtime 和操作系统,选择如下: 1.管理工具 - Docker Engine 2.runtime - runc 3.操作系统 (二)安装 ...
- Java集合(2)一 ArrayList 与 LinkList
目录 Java集合(1)一 集合框架 Java集合(2)一 ArrayList 与 LinkList Java集合(3)一 红黑树.TreeMap与TreeSet(上) Java集合(4)一 红黑树. ...
- MYSQL常见运算符和函数
字符函数 (1)CONCAT():字符连接 SELECT CONCAT('IMOOC','-','MySQL');//IMOOC-MySQL SELECT CONCAT (first_name,las ...
- ThreadLocal中的WeakReference
在一般的网站开发中,基于Java的Web 框架都使用了ThreadLocal来存储一些全局的参数,在拦截器\Filter中设置变量,让变量可以在任意地方被获取. 一早就了解到里面有用到WeakRefe ...
- [转]git问题ERROR: Repository not found.的解决
原文地址:http://blog.csdn.net/u010154424/article/details/51233966 在github中新增了一个项目,按照git的提示添加了远程仓库,但是提交的时 ...
- Codeforces 438D The Child and Sequence
题意:给定一个n个数的序列,完成以下3个操作: 1.给定区间求和 2.给定区间对x取模 3.单点修改 对一个数取模,这个数至少折半.于是我们记一个最大值max,如果x>max则不做处理. #in ...
- 一个看起来不像中年人的中年人,带着两个初出茅庐的小伙子儿,用git管理项目代码的进击之路
一个中年人的孤独前行 我们这一代人,是上个世纪的人,活在当下,已然成为社会上的中流砥柱. 80年代生人,遥望我们的父辈,均是5.60年代的人,迟迟暮年,夕夕老矣.而我们,正当年,却又时光飞逝,很快便要 ...