Domanda

Sto cercando di eseguire il debug di una perdita di descrittore di file in una webapp Java in esecuzione in Jetty 7.0.1 su Linux.

L'applicazione era stata felicemente in esecuzione per un mese o giù di lì quando le richieste hanno cominciato a fallire a causa di troppi file aperti , e Jetty doveva essere riavviato.

java.io.IOException: Cannot run program [external program]: java.io.IOException: error=24, Too many open files
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
    at java.lang.Runtime.exec(Runtime.java:593)
    at org.apache.commons.exec.launcher.Java13CommandLauncher.exec(Java13CommandLauncher.java:58)
    at org.apache.commons.exec.DefaultExecutor.launch(DefaultExecutor.java:246)

In un primo momento ho pensato che il problema era con il codice che lancia il programma esterno, ma è usando commons-exec e non vedo nulla di male con esso:

CommandLine command = new CommandLine("/path/to/command")
    .addArgument("...");
ByteArrayOutputStream errorBuffer = new ByteArrayOutputStream();
Executor executor = new DefaultExecutor();
executor.setWatchdog(new ExecuteWatchdog(PROCESS_TIMEOUT));
executor.setStreamHandler(new PumpStreamHandler(null, errorBuffer));
try {
    executor.execute(command);
} catch (ExecuteException executeException) {
    if (executeException.getExitValue() == EXIT_CODE_TIMEOUT) {
        throw new MyCommandException("timeout");
    } else {
        throw new MyCommandException(errorBuffer.toString("UTF-8"));
    }
}

file aperti quotazione sul server posso vedere un alto numero di FIFO:

# lsof -u jetty
...
java    524 jetty  218w  FIFO        0,6      0t0 19404236 pipe
java    524 jetty  219r  FIFO        0,6      0t0 19404008 pipe
java    524 jetty  220r  FIFO        0,6      0t0 19404237 pipe
java    524 jetty  222r  FIFO        0,6      0t0 19404238 pipe

quando Molo inizia ci sono solo 10 FIFO, dopo un paio di giorni ci sono centinaia di loro.

Lo so che è un po 'vago, in questa fase, ma hai qualche suggerimento su dove cercare prossimo, o come ottenere informazioni più dettagliate su tali descrittori di file?

È stato utile?

Soluzione

Il tuo programma esterno non si comporta correttamente. Date un'occhiata al motivo per cui non lo fa.

Altri suggerimenti

Il problema deriva dal l'applicazione Java (o una libreria che si sta utilizzando).

prima , si dovrebbe leggere l'intero uscite (Google per StreamGobbler), e pronto!

Javadoc dice:

  

Il processo genitore usa questi flussi   per alimentare ingresso e uscita da ottenere   il sottoprocesso. Poiché alcuni nativo   piattaforme forniscono solo buffer limitato   formato per input e output standard   corsi d'acqua, il mancato scrivere tempestivamente il   flusso in entrata o leggere il flusso in uscita   del sottoprocesso può causare   sottoprocesso per bloccare, e persino   situazione di stallo.

In secondo luogo , waitFor() il processo per terminare. È quindi dovrebbe chiudere i flussi di input, output e di errore.

Infine destroy() Process.

Le mie fonti:

Come si esegue su Linux ho il sospetto che si è a corto di descrittori di file. Scopri ulimit. Ecco un articolo che descrive il problema: http : //www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/

Non si conosce la natura della vostra applicazione, ma ho visto questo errore si manifesta più volte a causa di una perdita di pool di connessioni, in modo che sarebbe la pena di verificare. Su Linux, le connessioni socket consumano i descrittori di file e file del file system. Solo un pensiero.

Oltre a guardare in questioni come la causa principale di perdite di file, ecc, al fine di fare un aumento di legittima i "file aperti" limite ed avere che persistono dopo il riavvio, prendere in considerazione la modifica

/etc/security/limits.conf

con l'aggiunta di qualcosa di simile

jetty soft nofile 2048
jetty hard nofile 4096

dove "pontile" è il nome utente in questo caso. Per maggiori dettagli su limits.conf, vedi http://linux.die.net/man /5/limits.conf

disconnettersi e quindi accedere di nuovo ed eseguire

ulimit -n

per verificare che il cambiamento è avvenuto. Nuovi processi di questo utente dovrebbero ora rispettare questo cambiamento. Questo link sembra descrivere come applicare il limite di processi già avviato ma io non hanno provato.

Il limite predefinito 1024 può essere troppo bassa per le grandi applicazioni Java.

È possibile gestire i FDS da soli. L'exec in Java restituisce un oggetto processo. A intermittenza verificare se il processo è ancora in esecuzione. Una volta completato chiudi i processi flussi STDERR, STDIN e STDOUT (ad esempio proc.getErrorStream.close ()). Che attenuare le perdite.

Questo problema viene quando si sta scrivendo i dati in molti file contemporaneamente e il sistema operativo dispone un limite fisso di file aperti. In Linux, è possibile aumentare il limite di file aperti.

https://www.tecmint.com/ aumentare-set-open-file-limiti-in-linux /

Come faccio a cambiare la numero di file aperti limita in Linux?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top