现象

生产环境和測试环境都发现有个外围应用通过搜索服务调用搜索引擎时。偶尔会出现大量的訪问超时的问题,通过例如以下方式进行分析排查:

l 首先是拿到搜索服务的JavaCore。发现其堵在HttpClient的发送上面,被堵的连接有数百个,原因是不可以从连接池中获取到连接。

l 首先想到的就是连接池没有释放,检查代码,也确实存在着一些调用没有释放连接。特别是在异常的情况下,针对这一部分代码进行修复后。但是一段时间之后还是出现了訪问超时的问题;

l 考虑到这个外围应用的訪问现出问题的时候,其他的外围应用调用搜索服务是没有问题的,因此确定当前搜索服务还没有挂;

l 不同的外围应用可能调用的后台搜索引擎是不一样的。难道是该外围应用相应的搜索引擎出现了问题?只是经过对该搜索引擎进行分析。该搜索引擎本身是正常的,但是有一个奇怪的现象,在外围应用调用搜索服务发生超时时。搜索引擎本身没有接受到不论什么请求;

l 也就是说经搜索服务的请求都没有提交到该搜索引擎上。难道是搜索服务与该搜索引擎之间的连接有问题?通过网络排查,使用Ping和Telnet进行正向和反向确定,从搜索服务和搜索引擎之间的网络是正常的,且port也可以正常訪问。

l 再回到搜索服务所在的server,通过netstat一看。发现有400个CLOSE_WAIT与该搜索引擎相关的连接。这个数字恰好是应用中设置的单个Route所可以连接的最大连接数。

分析到此,问题就明朗了,HttpClient连接池的中创建连接数已经达到了最大数字。不可以创建新的连接了。已经创建的连接都是在等待关闭(CLOSE_WAIT)的状态,没有被放回到可用的连接池中,不可以用于处理新的连接请求,因而全部的请求都是堵在了从连接池中获取连接哪里。

要解决问题,首先须要知道CLOSE_WAIT产生的原因,才可以解决该问题。或者降低该问题的发生。

TCP连接关闭时须要四次握手才可以完毕。例如以下图所看到的:

产生CLOSE_WAIT状态的一方。是属于被动关闭的一方,用简单的话对解释上图(主动关闭方为A,被动关闭方为B):

A发一条FIN(关闭)请求给B。说我要关闭了。

B回应一条ACK(确认)请求给A,说我知道了。你关吧,此时B就会进行CLOSE_WAIT状态;

B发送一条FIN(关闭)请给A,说我要关闭了。

A收到发送一条ACK(确认)消息说,你关闭吧。

上面四次握手完毕后,两方的连接就都关闭了,但是这里在client产生了CLOSE_WAIT现象,首先可以确定的是服务端主动关闭的连接,且client没有给服务端发送关闭的请求(第三次握手请求),就会一直处在CLOSE_WAIT的状态。但是client为什么不向服务端发送关闭的请求。它当时在忙什么呢,难道应用在关闭前有哪么多事情要做?还有就是为什么服务会主动关掉client的这么多连接?

有人说这可能是服务端在调用关闭时,而client正在运行RECV(数据接收),这时候有可能服务端发送的FIN包client接收出错。就是由TCP代回了一个ACK包,所以client就会处在CLOSE_WAIT的状态中。因而建议推断RECV时是否出错。假设出错就主动关闭连接。这样就行防止没有接收到FIN包。

也有人说这是因为client请求服务端时,超时就有可能出现这样的情况,我对这样的情况做了实验,分别启动了client和服务端。在服务端中暴露一个超时的服务接口,在client中通过POST的方式调用,然后再通过第三方工具调用client去调用服务端的超时接口,測试分别在Linux以及Windows平台进行了測试,但是经过100万个连接超时的请求后,client没有出现CLOSE-WAIT的现象,仅仅有服务端才出现了CLOSE-WAIT,而且都会正常的关闭。

我们尝试过优化Linux中TCP连接參数,降低TCP的连接时间以及添加连接的可用性,例如以下:

sysctl -w net.ipv4.tcp_timestamps=0

sysctl -w net.ipv4.tcp_tw_reuse=1

sysctl -w net.ipv4.tcp_tw_recycle=1

sysctl -w net.ipv4.tcp_fin_timeout=30

sysctl -w net.ipv4.tcp_keepalive_time=1800

sysctl -w net.ipv4.tcp_rmem="4096 87380 8388608"

sysctl -w net.ipv4.tcp_wmem="4096 87380 8388608"

sysctl -w net.ipv4.tcp_max_syn_backlog=4096

也优化了HttpClient的參数。但是client还是会出现CLOSE_WAIT的情况,且搜索引擎是使用惠普的Autonomy,闭源的不好入手优化,最后还是通过在client实现定时任务定期检查当前连接中状态为leased(拿走但没有返回aviable可用队列中的连接)的连接的数量。检測到该这样的连接的数量超过一定数量后,就关闭该连接池,释放全部连接,然后又一次初使化该连接池,就行解决这样的问题了,经过測试这样的试是可行的。只是以前考虑到这样的方式比較暴力,连可用的连接都给关闭了,本想仅仅关闭那些长久未释放的连接,只是因为连接池没有暴露操作方法,通过反射可以获取到池中的连接,只是因为关联资源较多。操作麻烦,最后没有採用这样的方式。

client产生CLOSE_WAIT状态的解决方式的更多相关文章

  1. close_wait状态和time_wait状态(TCP连接)

    1.CLOSE_WAIT的简单解决方案 不久前,我的Socket Client程序遇到了一个非常尴尬的错误.它本来应该在一个socket长连接上持续不断地向服务器发送数据,如果socket连接断开,那 ...

  2. TCP连接的状态与关闭方式及其对Server与Client的影响

    TCP连接的状态与关闭方式及其对Server与Client的影响 1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用. ...

  3. TCP连接的状态与关闭方式,及其对Server与Client的影响

    1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用.特定数据包以及超时等,具体状态如下所示: CLOSED:初始状态, ...

  4. CLOSE_WAIT状态的原因与解决方法(转载留自己看)

    这个问题之前没有怎么留意过,是最近在面试过程中遇到的一个问题,面了两家公司,两家公司竟然都面到到了这个问题,不得不使我开始关注这个问题.说起CLOSE_WAIT状态,如果不知道的话,还是先瞧一下TCP ...

  5. close_wait状态的产生原因及解决(转)

    最近测试环境server由于需要与大量的后台server交互,今天突然发现有大量的close_wait产生,于是仔细研究了一下: 如果我们的服务器程序处于CLOSE_WAIT状态的话,说明套接字是被动 ...

  6. CLOSE_WAIT状态的原因与解决方法 --转

    转自:http://blog.chinaunix.net/uid-20357359-id-1963662.html 这个问题之前没有怎么留意过,是最近在面试过程中遇到的一个问题,面了两家公司,两家公司 ...

  7. HT for Web嵌入QtWebKit的client解决方式

    HTML5已经足够强大,但非常多应用还是须要独立桌面client的解决方式,毕竟能操作本地文件等功能还是非常多工具类软件短期内无法全然採用云方案替代. 近期Adobe公布的http://bracket ...

  8. Linux转发性能评估与优化-转发瓶颈分析与解决方式(补遗)

    补遗 关于网络接收的软中断负载均衡,已经有了成熟的方案,可是该方案并不特别适合数据包转发,它对server的小包处理非常好.这就是RPS.我针对RPS做了一个patch.提升了其转发效率. 下面是我转 ...

  9. redis的分布式解决方式--codis

    codis是豌豆荚开源的分布式server.眼下处于稳定阶段. 原文地址:https://github.com/wandoulabs/codis/blob/master/doc/tutorial_zh ...

随机推荐

  1. Android 学习笔记进阶14之像素操作

    在我们玩的游戏中我们会经常见到一些图像的特效,比如半透明等效果.要实现这种半透明效果其实并不难,需要我们懂得图像像素的操作. 不要怕,其实在Android中Bitmap为我们提供了操作像素的基本方法. ...

  2. Excel 2013数据挖掘工具栏的介绍(二)

    这里不多说,直接上干货! 上一篇博客是 下载安装与配置Excel 2013数据挖掘加载项(SQL Server 2012 SP1 + SQLServer2012_DMAddin.msi) Excel ...

  3. 【DRF版本】

    目录 使用内置的URLPathVersioning类 使用自定义的版本控制类 首先,我们开发的项目会有多个版本. 其次,我们的项目版本会随着更新越来越多,我们不可能因出了新版本就不维护旧版本了. 那么 ...

  4. 使用spring-boot 国际化配置所碰到的乱码问题

    写好html静态页面 ,  也加上了编码格式 , 获取国际化展示在浏览器中还是存在乱码 , 开始以为是浏览器编码格式问题 , 做过处理后任没有得到解决 , 具体的处理方案如下: <meta ht ...

  5. JQuery之为某个div加入行样式

    JQuery都是以$符号开头的.当然能够用jQuery取代$符号,他们是恒等的,同一时候也是相等的.()事实上就是一个方法,里面能够传递匿名函数等,选取某个div时,如id为div1则用$('#div ...

  6. cocoapod卡在了analyzing dependencies

    尽管公司的项目没有使用cocoapod,可是有一些第三方库本身依赖其它第三方的库,而且是用cocoapod来管理这些依赖的.所以在使用某些第三方库时.还是须要用到cocoapod的.今天在github ...

  7. 【基础练习】【线性DP】codevs2622 数字序列(最大连续子序列和)题解

    版权信息 转载请注明出处 [ametake版权全部]http://blog.csdn.net/ametake欢迎来看 这道题目本质就是朴素的最大连续子序列和 直接上题目和代码 题目描写叙述 Descr ...

  8. InstallShield详细制作说明(四)

    十.编译打包

  9. django 简单会议室预约(6)

    后台完了现在来看前端,前端用了一个bootstrap框架,看起来能好看点 先看一下文件结构:在djapp里创建了两个文件夹templates和static templates里面是要显示的页面,sta ...

  10. silverlight依据json字符串动态创建实体类

    1.接收json字符串: //用JsonValue转换json字符串是为了之后获得json字符串的每行数据和每一列的列名 JsonValue jv = JsonValue.Parse(json);   ...