V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gzk329
V2EX  ›  Java

遇到了个 Bug,查了下说是 tomcat 的 bug,新版本修复了,但是还会有这个问题?

  •  
  •   gzk329 · 160 天前 · 1767 次点击
    这是一个创建于 160 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ERROR org.apache.tomcat.util.net.Acceptor - Socket accept failed java.io.IOException: 打开的文件过多 at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:424) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:252) at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:466) at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:72) at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95) at java.lang.Thread.run(Thread.java:748)

    一开始我是调大了系统连接限制,发现还是会有这个问题,时间长点才出现罢了,连接数我不想调成无限制。
    我使用的是 tomcat 9.0.33 我查网上说是这个 bug tomcat 在 9.0.14 版本已经修复了?但我还是能遇到
    这说明是我自己的代码有泄漏吗?感觉也不大可能啊
    V 友 有遇到过吗?

    10 条回复    2023-09-15 08:35:36 +08:00
    me1onsoda
        1
    me1onsoda  
       160 天前
    是不是代码有问题,连接没释放掉?
    gzk329
        2
    gzk329  
    OP
       160 天前
    gzk329
        3
    gzk329  
    OP
       160 天前
    snowlyg
        4
    snowlyg  
       160 天前
    代码有问题的可能性更大,一般的软件不可能有这么大的漏洞
    yazinnnn
        5
    yazinnnn  
       160 天前
    ulimit -n 看看

    是不是代码里啥地方打开文件之后没关流?
    crsmk01
        6
    crsmk01  
       159 天前   ❤️ 6
    LZ 发的问题现象、排查步骤以及 github 中的引文,说是是个 bug ,感觉有点牵强附会。

    IOException:打开的文件过多,对应的英文应该是:Too many open files ,那应该查这个 Java 进程打开的文件描述符数和内容。

    在 Linux&Unix 操作系统下运行 Java 程序,如果用 root 用户运行,默认只有操作系统层面的限制,root 用户本身没限制,如果是普通用户,那么受普通用户下执行 ulimit -Hn ( ulimit -n 显示的是 soft limit ,而 Java 应用程序需要看 hard limit )数值的影响。在一些 Linux 操作系统下,一个普通用户打开的文件描述符默认是 1024 ,这个数值太小了,调大成 65535 或者稍微更大的值并没有问题(本来默认值就有点小,需要优化)。
    Linux 操作系统下,单进程可打开的文件描述符限制优先级:soft limit < hard limit < kernel (NR_OPEN => /proc/sys/fs/nr_open)

    如果 Java 程序运行在普通用户下,ulimit -Hn 参数值也优化过了,还是报 Too many open files ,那得看看这个 Java 进程到底是因为打开了啥导致的异常,具体看:ls -l /proc/<Java 进程 pid>/fd | more (内容会有点多),看看是文件,还是 established or close_wait 状态的 TCP 连接占用的多,根据看看到的异常输出结果,再去查资料也不迟。

    如果那个 Java 进程打开的文件描述符数处结果( ls -l /proc/<Java 进程 pid>/fd | more )也都正常,那就看看是不是操作系统层面所有用户、所有进程打开的文件描述符数是不是超过了操作系统最大允许打开的文件描述符数上限(/proc/sys/fs/file-nr )。
    Saturn72
        7
    Saturn72  
       159 天前
    @tdy218 专业!
    timeisweapon
        8
    timeisweapon  
       159 天前
    按照#6 大佬的方法排查文件句柄数,个人经验大概率是应用的问题
    ntop
        9
    ntop  
       159 天前
    我曾经遇到过类似的问题,但是并不是 java 而是其它语言,导致问题的原因是,当时有一个系统负责处理数据,大概逻辑就是一旦有一个请求过来我就会开启一个线程取读写数据库,但是如果同一时间产生了大量的读写请求并且读写操作耗时较长,那么就会在数秒之内打开太多的文件从而导致这个问题。
    matepi
        10
    matepi  
       159 天前
    一般都是连接泄露
    lsof -n -P > result.txt
    然后拿下来看。

    如果超大量 CLOSE_WAIT ,要考虑内部存在的服务请求等网络请求、在超时设定上的合理性。内层网络调用超时应小于外层网络调用超时,并逐层保证。如果使用 netty 等非线程池、使用事件 LOOP 处理的,更会容易触发此种情况。

    同时,可以通过 jstack 等做个 threaddump 分析,有可能快速定位问题程序栈位置。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5656 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 06:01 · PVG 14:01 · LAX 22:01 · JFK 01:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.