重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
tcp socket文件句柄泄漏
创新互联公司是一家专注于成都做网站、成都网站建设与策划设计,呼图壁网站建设哪家好?创新互联公司做网站,专注于网站建设十余年,网设计领域的专业建站公司;建站业务涵盖:呼图壁等地区。呼图壁做网站价格咨询:18982081108今天发现有台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连接数并不是很多。
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
而我的系统监控取值方法是:
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 sock
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、解决方案
今天发现,重启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的日志。
另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。