zoukankan      html  css  js  c++  java
  • tcp socket文件句柄泄漏【转】

    转自:http://www.178linux.com/2468

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

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

    netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"	",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

  • 相关阅读:
    GenericServlet和HttpServlet有什么区别?
    什么是RMI?
    【WPF学习】第十八章 多点触控输入
    【WPF学习】第十七章 鼠标输入
    【WPF学习】第十六章 键盘输入
    【WPF学习】第十五章 WPF事件
    【WPF学习】第十四章 事件路由
    【WPF学习】第十三章 理解路由事件
    【WPF学习】第十二章 属性验证
    【WPF学习】第十一章 理解依赖项属性
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/12100705.html
Copyright © 2011-2022 走看看