当前位置: 首页 > 知识库问答 >
问题:

tomcat"打开的文件太多"出错

徐正雅
2023-03-14

我有一个在tomcat上运行的应用程序,有时会出现以下错误:

SEVERE: Socket accept failed
java.net.SocketException: Too many open files
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
at java.net.ServerSocket.implAccept(ServerSocket.java:522)
at java.net.ServerSocket.accept(ServerSocket.java:490)
at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60)
at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:216)
at java.lang.Thread.run(Thread.java:722)

....

SEVERE: Error processed default web.xml named conf/web.xml at /local/myApp/apache-tomcat/conf/web.xml
java.io.FileNotFoundException: /local/myApp/apache-tomcat/conf/web.xml (Too many open files)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at org.apache.catalina.startup.ContextConfig.getWebXmlSource(ContextConfig.java:1838)
        at org.apache.catalina.startup.ContextConfig.getGlobalWebXmlSource(ContextConfig.java:1745)
        at org.apache.catalina.startup.ContextConfig.getDefaultWebXmlFragment(ContextConfig.java:1418)
        at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1253)
        at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:878)
        at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:369)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5269)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3926)
        at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
        at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
        at java.lang.Thread.run(Thread.java:722)

我检查了打开文件的限制,它是1024个,但是当我检查了lsof应用程序的打开文件数量时,它接近200个,如果它没有达到限制,为什么会发生这种情况?我应该增加限额吗?是否有其他原因导致此错误?让服务重新正常运行的唯一方法是重新启动tomcat,还有其他恢复正常的方法吗?

提前谢谢。

编辑:这里是处理doPost方法的servlet,一开始我没有关闭每个流,会是这样吗?我添加了这样做的最后声明

    InputStream is = null;
    DataInputStream dis = null;
    OutputStream os = null;
    DataOutputStream dos = null;
    String paramName = "";
    try {
        os = response.getOutputStream();
        is = request.getInputStream();
        dis = new DataInputStream(is);
        dos = new DataOutputStream(os);
        .....
        }catch (Throwable e) {
        LOGGER.error(e.getMessage());
        } finally {
          if (dis != null) {
             dis.close();
           }
           else if(is != null) {
             is.close();
           }                
           if (dos != null) {
             dos.close();
           }
           else if( os != null) {
             os.close();
           }
        }

EDIT2:在做了一些测试后,我意识到如果我先关闭数据输入流,然后关闭输入流,我在通信的另一部分得到一个数字在消息之前(我不知道为什么)。我改变了关闭流的顺序,似乎一切都好。但是我仍然有问题。任何想法?

  finally {

    if(is != null) {
        try {
            is.close();
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
    }
    if (dis != null) {
        try {
            dis.close();
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
    }
    if(os != null) {
        try {
            os.close();
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
    }
    if (dos != null) {
        try {
            dos.close();
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
    }
}

共有3个答案

卢树
2023-03-14

您可以通过在/etc/security/limits中添加以下内容来更改打开文件的限制,这可能会很有用。形态

* soft nofile 2048 # Set the limit according to your needs
* hard nofile 2048

然后您可以使用shell上的sysctl-p重新加载配置。检查这篇文章。

为了完整起见,您可以使用:ulimit-n

崔单弓
2023-03-14

按照以下说明快速分析服务器的当前配置,并调整tomcat硬限制和软限制以解决此问题。

这将显示该进程的所有打开的文件。

ls -l /proc/tomcatPID/fd 

这将显示打开文件的计数。

ls -l /proc/tomcatPID/fd | wc -l 

增加打开文件限制更新/etc/security/limits。conf

要检查特定于tomcat的未打开文件:

硬限制:su-tomcat-c'ulimit-Hn'-s'/bin/bash'

软限制:su-tomcat-c'uLimited-Sn'-s'/bin/bash'

您可以使用corn作业运行下面的脚本,以了解打开文件的详细信息。

=============================
#!/bin/bash

PID=$(ps -ef|grep tomcat6|grep -v grep |awk '{print $2}')
value=$(ls -l /proc/$PID/fd | wc -l)
echo `date`@$PID:$value >> /usr/local/filecount.txt
if [ $value -gt 2000 ];
then
printf "\n\n\n\n\n" >> /usr/local/files_report.txt
echo "-------------------------------`date`--Starting Session----------------------" >> /usr/local/files_report.txt
openfiles=$(ls -l /proc/$PID/fd | awk '{print NR,$11 "" >> "/usr/local/files_report.txt"}')
echo "--------------------`date`---Ending  Session ------------------------------" >> /usr/local/files_report.txt
fi
================= 
左丘兴生
2023-03-14

执行以下操作以获取tomcat7的pid,比如1234

ps aux |grep tomcat7

然后呢

cat /proc/1234/limits读取如下一行

最大打开文件16384 16384文件

这是Tomcat允许的最大打开文件数。要增加它,请按照以下说明操作

Tomcat打开的文件太多。

 类似资料:
  • 今天早些时候,我访问了我最近推出的一个网站,页面上充斥着一个丑陋的jasperex0019:java.io.filenotfoundexception: /opt/tomcat/webapps/root/web-inf/lib/jstl-1.2.jar(打开的文件太多)。我检查了我的服务器日志和tomcat日志,它们充满了相同的错误。我增加了tomcat的最大打开文件限制,作为保持网站运行的临时解

  • 我想知道太多文件打开错误的确切问题。我通过谷歌寻找解决方案,但我不知道为什么会出现这个问题以及如何解决这个问题。 堆栈错误:严重:套接字接受失败。网SocketException:java上打开的文件太多。网普通袜子。java上的socketAccept(本机方法)。网抽象素socketimpl。在java上接受(AbstractPlainSocketImpl.java:398)。网服务器插座。j

  • 我们正在AmazonLinux中的ApacheTomcat中运行一个web服务。最初web服务运行正常。在发出1000多个web请求后,我们收到了太多的打开文件异常。当我们重新启动tomcat服务器时,这个问题将再次得到解决。 请查看以下例外情况 附言:我们在网络服务中没有做任何与文件相关的操作。

  • 从Tomcat 7迁移到Tomcat 9.0之后。20(使用相同的Java版本1.8.0_25运行)我们在Linux RHEL 7上的JSF2 web应用程序存在问题。一段时间后,我们会遇到如下异常: 经过一段时间的搜索,我发现xhtml文件有许多打开的文件描述符,通过执行这个命令(其中4025是Tomcat进程ID): 这不是完整的列表-还有很多。 列出的文件数量会上下波动。对我来说,只要页面在

  • 问题内容: 我使用多个文件来执行一些文件I / O(写入19个文件,确实如此)。写他们几百次后,我得到了。但实际上我一次只能打开几个文件。这里有什么问题?我可以验证写入是否成功。 问题答案: 在Linux和其他UNIX /类似UNIX的平台上,操作系统对进程在任何给定时间可能具有的打开文件描述符的数量进行了限制。在过去,此限制曾经是硬接线1,并且相对较小。如今,它要大得多(几百/千),并且受“软”

  • 问题内容: 我写了一种测试套件,它占用大量文件。一段时间(2h)之后,我得到了。我仔细检查了所有文件句柄是否再次关闭它们。但是错误仍然存​​在。 我试图找出使用允许的文件描述符的数量以及当前打开的文件描述符的数量: 因此,如果我运行以下测试: 我得到以下输出: 真奇怪,我期望打开的文件描述符会越来越多。我的脚本正确吗? 我正在使用python的记录器和子进程。那可能是我FD泄漏的原因吗? 谢谢,丹