wake-up-neo.com

Fehler in Tomcat "zu viele offene Dateien"

Ich habe eine Anwendung, die auf Tomcat ausgeführt wird, und manchmal habe ich den folgenden Fehler:

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)

Ich überprüfe die Grenzen der geöffneten Dateien und es sind 1024, aber wenn ich die Anzahl der geöffneten Dateien der Anwendung mit lsof überprüfe, sind es fast 200. Warum passiert dies, wenn die Grenze nicht erreicht wird? Soll ich die Grenze erhöhen? Gibt es einen anderen Grund, um diese Fehlermeldung zu erhalten? Die einzige Möglichkeit, den Dienst wieder ordnungsgemäß auszuführen, besteht darin, den Tomcat neu zu starten. Gibt es eine andere Möglichkeit, zur Normalität zurückzukehren?

Danke im Voraus.

EDIT: Hier ist das Servlet, das die doPost-Methode verarbeitet. Zu Beginn habe ich nicht jeden Stream geschlossen. Könnte es das sein? Ich habe die abschließende Aussage dazu hinzugefügt:

    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: Nach einigen Tests erkenne ich, dass ich, wenn ich zuerst den DataInputStream und dann den InputStream schließe, im anderen Teil der Kommunikation eine Nummer vor der Nachricht bekomme (ich weiß nicht warum). Ich habe die Reihenfolge beim Schließen des Streams geändert und es scheint, dass alles in Ordnung ist. Aber ich habe immer noch das Problem. Irgendeine Idee?

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

Gehen Sie folgendermaßen vor, um die PID von 1237 zu erhalten

ps aux |grep Tomcat7

und dann tun 

cat /proc/1234/limits, um eine Zeile wie folgt zu lesen

Max open files 16384 16384 files 

Dies ist die maximale Anzahl offener Dateien, die von Tomcat zugelassen wird. Um es zu vergrößern, folgen Sie den Anweisungen unten

Zu viele offene Dateien Tomcat.

13
Zouzias

Es kann nützlich sein zu wissen, dass Sie das Limit der geöffneten Dateien ändern können, indem Sie Folgendes zu /etc/security/limits.conf hinzufügen:

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

Anschließend können Sie die Konfiguration mit sysctl -p in der Shell erneut laden. Überprüfen Sie diesen Artikel .

Der Vollständigkeit halber können Sie anhand folgender Angaben überprüfen, wie hoch das aktuelle Limit für geöffnete Dateien ist: ulimit -n

8
gaboroncancio

Dadurch werden alle geöffneten Dateien dieses Prozesses angezeigt.

ls -l /proc/tomcatPID/fd 

Dadurch wird die Anzahl der geöffneten Dateien angezeigt.

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

Um die Anzahl offener Dateien zu erhöhen, aktualisieren Sie /etc/Secirity/limits.conf.

So überprüfen Sie keine der für Tomcat spezifischen offenen Dateien:

Harte Grenze: su - Tomcat -c 'ulimit -Hn' -s '/bin/bash'

Soft-Limit: su - Tomcat -c 'ulimit -Sn' -s '/bin/bash'

Sie können unter einem Skript einen Maisauftrag ausführen, um die Details der geöffneten Dateien zu erfahren.

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

Die Antwort, die @gaboroncancio gepostet hat, ist grundsätzlich richtig, aber seine Ratschläge, wie die Einstellungen wirksam werden sollen, sind nicht ganz richtig. sysctl -p lädt /etc/sysctl.conf oder die Datei, die Sie als Argument übergeben, erneut. Der Befehl sysctl erkennt jedoch nicht das Format von /etc/security/limits.conf.

Um /etc/security/limits.conf erneut zu laden, müssen Sie sich lediglich abmelden und erneut anmelden.

4
lietuviuHimnas
  1. Wenn dieser Code von Netzoperationen (Sockets) stammt, bin ich nicht sicher, ob Java XxxxxStrem eine 1: 1-Beziehung zu den OS-Dateilimits hat (oder überhaupt eine Beziehung hat). Vielleicht brauchen Sie etwas Nachforschung, Ausnahmemeldung hat falschen Text? Sehr oft in Software.

  2. Meine Intuition sagt, wir verstehen nicht, Ausnahme 2, nichts in Code (oder Konfiguration, die in Frage stehen) hat eine Beziehung. 

  3. Das Erweitern der Dateien von Betriebssystemdateien, wenn ein Softwarefehler (Leck) das Hauptproblem ist, ist eine schlechte Richtlinie, wie Sie es gut verstehen

0
Jacek Cz