tcp socket文件句柄泄漏

今天发现有台redis机器上出现socket个数告警,这是很奇怪的现象。因为一台redis服务器上就部署了几个redis实例,打开的端口应该是有限。

1、netstat显示的tcp连接数正常

netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
TIME_WAIT        221
ESTABLISHED      103
 
netstat  -nat |wc -l
368

建立的tcp连接数并不是很多。

2、ss -s显示大量的closed连接

ss -s
Total: 158211 (kernel 158355)
TCP:   157740 (estab 103, closed 157624, orphaned 0, synrecv 0, timewait 173/0), ports 203
 
Transport Total     IP        IPv6
*         158355    -         -        
RAW       0         0         0        
UDP       9         6         3        
TCP       116       80        36       
INET      125       86        39       
FRAG      0         0         0

closed 157624,很多socket是处于closed状态。

而我的系统监控取值方法是:

cat /proc/net/sockstat | grep sockets | awk '{print $3}'
158391
 
cat /proc/net/sockstat
sockets: used 158400
TCP: inuse 89 orphan 2 tw 197 alloc 157760 mem 16
UDP: inuse 6 mem 0
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

很多socket处于alloc状态,已经分配sk_buffer,而且处于closed。

redis的file discriptes存在泄漏,没有被内核回收。

3、追查真凶
上面信息说明存在socket fd泄漏,那么用lsof命令检查系统sock的文件句柄。

lsof | grep sosck
java        4684      apps *280u     sock                0,6       0t0 675441359 can't identify protocol
java        4684      apps *281u     sock                0,6       0t0 675441393 can't identify protocol
java        4684      apps *282u     sock                0,6       0t0 675441405 can't identify protocol
java        4684      apps *283u     sock                0,6       0t0 675441523 can't identify protocol
java        4684      apps *284u     sock                0,6       0t0 675441532 can't identify protocol
java        4684      apps *285u     sock                0,6       0t0 675441566 can't identify protocol

可以发现,Name列的值为“an’t identify protocol”,socket找不到打开的文件,。

这个显示,是java进程(pid=4684)出现了socket fd泄漏的状况。

ps auxww | grep 4684

发现是redis机器上日志收集工具flume。

4、解决方案
没有很好的的方法,简单粗暴的kill占有scoket fd的进程。
<更新于2015年3月11日 20:05:30>
今天发现,重启flume agent之后,仍然会出现这种大量的closed socket现象。
strace flume进程,发现flume进程已经挂起了。

sudo strace -p 36111
Process 36111 attached - interrupt to quit
futex(0x2b80e2c2e9d0, FUTEX_WAIT, 36120, NULL

首先,我比较怀疑文件句柄不够用,因为google查找到的资料也提高了文件fd不够而导致这种问题。

在我的机器上,最大允许打开的文件数为131072,文件fd个数还有近1/4没有使用。

  lsof | wc -l 
10201
 
ulimit -a 
ulimit  -n
131072

这时,同事提示我,还有其他大量机器也出现了这种问题(flume已经上线了3个月,之前都很正常)。

这是,我想起了还有flume的日志可以查看。而查看flume的日志,提示flume找不到broker 5。
纳尼,不是kafka集群不是只有4个broker(节点)。这时候才想起前几天的邮件然来spark开发的同事,对kakf集群进行扩容了。
而新的集群节点9092端口对这台redis所在的机房没有开放访问权限。

 [SinkRunner-PollingRunner-DefaultSinkProcessor] (kafka.utils.Logging$class.warn:89)  - Failed to send producer request 
with correlation id 63687539 to broker 5 with data for partitions [titan,4]

5、问题重现

在lsof: can’t identify protocol这篇文章中,用python代码重现了这种状况。

:)

在解决问题时,google查找是一种比较快捷的方式。而有时候,google出来的结果反而会影响排查问题的方向。
在我看到google的搜索结果之后,第一感觉是因为操作系统的max open files参数太小导致。在发现不是这个原因之后。我的思路仍然停留在内核参数是否配置合理的思路上。知道其他的机器上部署的flume出现了同种状况是,我才意识到是flume本身出了问题,才去strace flume进程的状态和查看flume的日志。

转自:http://mdba.cn/?p=762

原创文章,作者:s19930811,如若转载,请注明出处:http://www.178linux.com/2468

(1)
s19930811s19930811
上一篇 2016-04-13 11:54
下一篇 2016-04-13 11:54

相关推荐

  • 文件查找命令之find

    文件查找命令之find   特点:实时查找,精确查找,由于find是全磁盘文件查找所有查找速度要比locate略慢一些。   find查找功能强大,下面主要介绍find查找条件的一个重要特性–德·摩根定律     德·摩根定律      非(A &&B)=(非A…

    Linux干货 2016-08-16
  • N21第五周

    1.显示/boot/grub2/grub.cfg中以至少一个空白字符开头的行; ]# grep '^[[:space:]]\+' /boot/grub2/grub.cfg 2.显示/etc/rc.d/init.d/functions文件中以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行; ]#…

    Linux干货 2016-08-15
  • LVS的四种模型

    相关术语: vs:Virtual Server,Director,Dispatcher,Balancer rs:Real Server,upstream server,backend server lvs集群的类型: lvs-nat:修改请求报文的目标IP lvs-dr:操作封装新的MAC地址; lvs-tun:在原请求IP报文之外新加一个IP首部; lvs…

    Linux干货 2016-10-30
  • Haproxy+keepalivd+LAMP

    目录 一、试验部署 1、实验要求 2、实验准备 3、拓扑结构 4、网络规划 二、基础设置 1、LAMP配置 2、HAProxy配置 3、Keepalived配置 三、测试 四、总结 一、试验部署 1、实验要求 (1) 动静分离部署wordpress,动静都要能实现负载均衡,要注意会话的问题; (2) 给出设计拓扑,写成博客; (3)haproxy的设定要求:…

    2017-05-18
  • 马哥网络教育班21期+第一周博客作业

    1、描述计算机的组成及其功能。   硬件:     CPU(运算器、控制器、一缓存(L1)、二级缓存(L2)):       运算器主要用来进行算数运算以及逻辑运算。       控制器主要是用来协调       一级缓存和二级缓存主要是用…

    Linux干货 2016-07-12
  • 文本查找相关命令简单介绍

    文件查找命 在文件系统上查找符合条件的文件 非实时查找:基于索引查找 locate 实时查找:find locate介绍 依赖于事先构建的索引:索引的构建是在系统较为空闲时自动进行(周期性任务):手动更新数据库(updatedb) 索引构建过程需要遍历整个根文件系统,极消耗资源,生产中尽量避免手动更新。 语法: locate KEYWORD -i:忽略大小写…

    Linux干货 2017-04-10