tcp socket文件句柄泄漏【转】
转自:http://www.178linux.com/2468
今天发现有台redis机器上出现socket个数告警,这是很奇怪的现象。因为一台redis服务器上就部署了几个redis实例,打开的端口应该是有限。
1、netstat显示的tcp连接数正常
1 2 3 4 5 6 | 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连接
1 2 3 4 5 6 7 8 9 10 11 | 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状态。
而我的系统监控取值方法是:
1 2 3 4 5 6 7 8 9 10 | 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的文件句柄。
1 2 3 4 5 6 7 | 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泄漏的状况。
1 | ps auxww | grep 4684 |
发现是redis机器上日志收集工具flume。
4、解决方案
没有很好的的方法,简单粗暴的kill占有scoket fd的进程。
<更新于2015年3月11日 20:05:30>
今天发现,重启flume agent之后,仍然会出现这种大量的closed socket现象。
strace flume进程,发现flume进程已经挂起了。
1 2 3 | sudo strace - p 36111 Process 36111 attached - interrupt to quit futex( 0x2b80e2c2e9d0 , FUTEX_WAIT, 36120 , NULL |
首先,我比较怀疑文件句柄不够用,因为google查找到的资料也提高了文件fd不够而导致这种问题。
在我的机器上,最大允许打开的文件数为131072,文件fd个数还有近1/4没有使用。
1 2 3 4 5 6 | lsof | wc - l 10201 ulimit - a ulimit - n 131072 |
这时,同事提示我,还有其他大量机器也出现了这种问题(flume已经上线了3个月,之前都很正常)。
这是,我想起了还有flume的日志可以查看。而查看flume的日志,提示flume找不到broker 5。
纳尼,不是kafka集群不是只有4个broker(节点)。这时候才想起前几天的邮件然来spark开发的同事,对kakf集群进行扩容了。
而新的集群节点9092端口对这台redis所在的机房没有开放访问权限。
1 2 | [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的日志。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
2018-12-26 android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论【转】
2017-12-26 Linux进程调度原理【转】
2017-12-26 Linux进程核心调度器之主调度器schedule--Linux进程的管理与调度(十九)【转】
2017-12-26 Tslib触摸屏官网【转】
2017-12-26 Tslib的移植【转】