Too many file open 问题排查记录

本贴最后更新于 1636 天前,其中的信息可能已经东海扬尘

Too many file open 问题排查记录

环境

  • Tocmat 8.0
  • CentOS6.4
  • JDK 8

问题描述

系统部署到云环境后,当天工作正常,第二天就无法正常工作,看了 Tomcat 日志,日志中频繁出现 Too many file open 的报错,重启项目后,可以恢复正常。

问题排查记录

  1. 问题已产生,且未重启 Tomcat 服务
  2. 查看 Tomcat 进程的 PID
ps -ef | grep tomcat

获取到 TomcatPID 用于查看 Tomcat 进程的连接句柄

  1. 使用 lsof 命令,查看了 Tomcat 进程的连接句柄数
# 按TYPE降序查看连接句柄数量 lsof -n | grep PID | awk '{print $5}' | sort | uniq -c | sort -nr | head -n 10 # 按NAME降序查看连接句柄数量 lsof -n | grep PID | awk '{print $9" "$10}' | sort | uniq -c | sort -nr | head -n 10

查看后发现句柄数量最多的是

  • TYPEsocket
  • NAMEcan't identify protocol

经过度娘之后,得知这种 can't identify protocol 的 socket 句柄,通常是 socket 流使用后,没有关闭 socket 流导致,于是开始着手定位代码问题。

  1. 找到问题接口
    找一个同样的环境且没有干扰情况下,需要准备一个小脚本,时刻监控 NAMEcan't identify protocol 的连接句柄数量
    test.sh

    #!/bin/sh while [ true ]; do lsof -n | grep $1 | awk '{print $9" "$10}' | sort | uniq -c | sort -nr | head -n 10 sleep 1 done
    chmod +x test.sh ./test.sh tomcat_pid

    启动后就可以每秒刷新一次,监控 Tomcat 进程 NAMEcan't identify protocol 的连接句柄数量。

    开始逐一测试线上接口,定位问题,每调用接口前后,观察 NAME can't identify protocol` 的连接句柄数量的增长情况,找到问题接口。

  2. 定位代码问题
    找到问题接口后,开启 Tomcat 远程调试功能
    修改 $TOMCAT_HOME/bin/catalina.sh 中 JPDA_ADDRESS 这一项,将内容改为需要绑定的远程调试端口

    268 if [ "$1" = "jpda" ] ; then 269 if [ -z "$JPDA_TRANSPORT" ]; then 270 JPDA_TRANSPORT="dt_socket" 271 fi 272 if [ -z "$JPDA_ADDRESS" ]; then 273 JPDA_ADDRESS="5050" 274 fi 275 if [ -z "$JPDA_SUSPEND" ]; then 276 JPDA_SUSPEND="n" 277 fi 278 if [ -z "$JPDA_OPTS" ]; then 279 JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND" 280 fi 281 CATALINA_OPTS="$CATALINA_OPTS $JPDA_OPTS" 282 shift 283 fi

    修改PRGDIR"/"@"改为 exec "EXECUTABLE" jpda start "$@"`

    42 EXECUTABLE=catalina.sh 43 44 # Check that target executable exists 45 if $os400; then 46 # -x will Only work on the os400 if the files are: 47 # 1. owned by the user 48 # 2. owned by the PRIMARY group of the user 49 # this will not work if the user belongs in secondary groups 50 eval 51 else 52 if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then 53 echo "Cannot find $PRGDIR/$EXECUTABLE" 54 echo "The file is absent or does not have execute permission" 55 echo "This file is needed to run this program" 56 exit 1 57 fi 58 fi 59 60 exec "$PRGDIR"/"$EXECUTABLE" jpda start "$@"

    开放防火墙的远程调试端口

    /sbin/iptables -I INPUT -p tcp --dport 5050 -j ACCEPT /etc/rc.d/init.d/iptables save /etc/rc.d/init.d/iptables restart

    重启 Tomcat 服务

    使用 IDEA 远程调试 Tomcat(需要本地代码与线上代码完全一致,否则不会进入断点)

    请求接口,逐行调试,观察 NAME can't identify protocol` 的连接句柄数量的增长情况,找到问题代码,并修改

  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 2 关注
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    239 引用 • 224 回帖 • 1 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    9765 引用 • 44423 回帖 • 88 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...