簡體   English   中英

tomcat中的錯誤“打開的文件太多”

[英]Error in tomcat "too many open files"

我有一個在 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,一開始我沒有關閉每個流,可能是這樣嗎? 我為此添加了 finally 語句:

    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:在進行了一些測試之后,我意識到如果我先關閉 DataInputStream 然后關閉 InputStream,我會在消息之前的另一個部分獲得一個數字(我不知道為什么)。 我更改了關閉流的順序,似乎一切正常。 但我仍然有問題。 任何的想法?

  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());
        }
    }
}

執行以下操作以獲取 tomcat7 的 pid,例如 1234

ps aux |grep tomcat7

然后做

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

Max open files 16384 16384 files

這些是 Tomcat 允許的最大打開文件數。 要增加它,請按照以下說明操作

Tomcat 打開的文件太多。

按照以下說明快速分析服務器的當前配置,並調整 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 'ulimit -Sn' -s '/bin/bash'

您可以使用玉米作業運行以下腳本以了解打開文件的詳細信息。

=============================
#!/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
================= 

知道您可以通過將以下內容添加到/etc/security/limits.conf來更改打開文件的限制可能很有用:

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

然后您可以在 shell 上使用sysctl -p重新加載配置。 檢查這篇文章

為了完整起見,您可以使用以下命令驗證打開文件的當前限制: ulimit -n

@gaboroncancio 發布的答案基本正確,但他關於如何使設置生效的建議不太正確。 sysctl -p將重新加載/etc/sysctl.conf或您作為參數傳入的任何文件。 但是, sysctl命令不會識別/etc/security/limits.conf的格式。

要重新加載/etc/security/limits.conf ,您只需要注銷並重新登錄。

  1. 如果此代碼來自網絡操作(套接字),我不確定 Java XxxxxStrem 與 OS 文件限制有 1:1 的關系(或根本沒有關系)。 也許需要一些研究,異常消息有錯誤的文本? 經常在軟件中。

  2. 我的直覺說,我們不理解異常 2,代碼中的任何內容(或沒有問題的配置)都沒有關系。

  3. 當軟件錯誤(泄漏)是主要問題時擴展操作系統文件限制是不好的政策,正如您所理解的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM