现象

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

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. js---跨域的问题

    一:跨域一般的报错情况  一般来说,如果你在开发中需要进行跨域操作(从一个非同源网站发送请求获取数据),一般而言,你在浏览器控制台看到的结果为: 二:同源策略 说到跨域就不得不提“同源策略”. 那么, ...

  2. IOS应用在ios7(iPhone5/iPhone5s)上不能全屏显示

    前言 [IOS应用在iOS7系统或者iPhone5/iPhone5s上不能全屏显示,应用画面上下各有1条黑色,但是在其他系统或者型号的手机上却是正常显示 Paste_Image.png Paste_I ...

  3. 常用的130个vim命令

    最近VIM用的也越来越多了...因为确实在慢慢的把win下的编辑习惯转成unix下的编辑习惯..._vimrc也在不断的完善中先贴一下平时在VIM中使用中的命令...有很多也是我没有掌握的 (估计也是 ...

  4. docker的数据持久化

    挂载宿主机的目录(实现很多容器共用一个宿主卷) [root@localhost ~]# docker run -itd --name web01 -v /var/www/html:/var/www/h ...

  5. Spring Cloud Sleuth通过Kafka将链路追踪日志输出到ELK

    1.工程简介 elk-eureka-server作为其他三个项目的服务注册中心 elk-kafka-client调用elk-kafka-server,elk-kafka-server再调用elk-ka ...

  6. 洛谷 P2867 [USACO06NOV]大广场Big Square

    P2867 [USACO06NOV]大广场Big Square 题目描述 Farmer John's cows have entered into a competition with Farmer ...

  7. 2.5 Legacy APIs官网剖析(博主推荐)

    不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ 2.5 Legacy APIs A more limited legacy prod ...

  8. JS/CSS 在屏幕底部弹出消息

    <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...

  9. 3.字符设备驱动------Poll机制

    1.poll情景描述 以之前的按键驱动为例进行说明,用阻塞的方式打开按键驱动文件/dev/buttons,应用程序使用read()函数来读取按键的键值. ) { read(fd, &key_v ...

  10. prettyJson V7.1 使用

    头文件 #include "document.h" #include "prettywriter.h" #include "filereadstrea ...