现象

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

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. 暑假集训-二分图,网络流,2-SAT

    匈牙利算法DFS bool dfs(int u){ ; i <= n; i++){ if(a[u][i] && !visit[i]){ visit[i] = true; || d ...

  2. Elasticsearch之shield(权限)插件安装之后的浏览详解

    前期博客 Elasticsearch-2.4.3的3节点安装(多种方式图文详解)(含 head.kopf.marvel.shield和watcher插件安装和使用) 访问es:-u es_admin ...

  3. ie中 专有的注释

    http://www.cnblogs.com/liluping860122/p/3539165.html

  4. Gym 100952 C. Palindrome Again !!

    http://codeforces.com/gym/100952/problem/C C. Palindrome Again !! time limit per test 1 second memor ...

  5. C_深入(内存模型)

    01 数据类型: 为什么有数据类型? 现实生活中的数据太多而且大小形态不一. 数据类型与内存的关系: 数据类型的本质:创建变量的模具,是固定大小的别名. #include "stdio.h& ...

  6. Swift具体解释之三----------函数(你想知道的都在这里)

    函数(你想知道的都在这里) 注:本文为作者自己总结.过于基础的就不再赘述 ,都是亲自測试的结果.如有错误或者遗漏的地方.欢迎指正.一起学习. 1. 函数的简单定义和调用 简单的无參函数就不再赘述 , ...

  7. List-ArrayList 使用

    今天优化一段代码,如下 int num = 0; boolean skipAppend = false; int types_ext1[] = new int[] { ModuleType.TYPE_ ...

  8. 很好的资源 for android

    //texttospeach http://examples.javacodegeeks.com/android/core/text-to-speech/android-text-to-speech- ...

  9. BZOJ4372: 烁烁的游戏(动态点分治)

    Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮 ...

  10. BZOJ 3732 Network Kruskal+倍增LCA

    题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 NOIP2013 货车运输.差点儿就是原题...仅仅只是最小边最大改成了最大边最小.. . 首先看到最大值最小第一 ...