Log4j sta bloccando la mia applicazione che cosa sto facendo di sbagliato?
-
10-07-2019 - |
Domanda
Prima alcuni retroscena sull'applicazione. Ho un'applicazione che elabora molte attività indipendenti in parallelo tramite un pool di thread. Il pool di thread è ora sospeso.
Quello che segue è un frammento dei miei dump di thread, tutti i miei thread nel pool-2 sono BLOCCATI da " pool-2-thread-78 " ;. Sembra essere bloccato cercando di scrivere sulla console che trovo estremamente strano. Qualcuno può fare luce sulla situazione per me?
Modifica : Dettagli della piattaforma versione java " 1.6.0_07 " Java (TM) SE Runtime Environment (build 1.6.0_07-b06) VM client HotSpot (TM) Java (build 10.0-b23, modalità mista, condivisione)
Macchina dual quad core per server Ubuntu Linux.
Sembra che si blocchi durante la scrittura sul flusso di stampa, ho preso in considerazione solo la rimozione dell'appender della console, ma preferirei sapere perché lo sta bloccando e rimuoverlo in base a questa conoscenza. In passato il rimuovere e vedere se funziona è tornato a mordermi :)
sezione pertinente dal mio log4j
log4j.rootLogger = DEBUG, STDOUT log4j.logger.com.blah = INFO, LOG log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender log4j.appender.LOG = org.apache.log4j.FileAppender
Estratto di dump del thread
" piscina-2-thread-79 quot &; Id = 149 BLOCCATO attivo org.apache.log4j.spi.RootLogger@6c3ba437 di proprietà di " pool-2-thread-78 " Id = 148 a org.apache.log4j.Category.callAppenders (Category.java:201) a org.apache.log4j.Category.forcedLog (Category.java:388) a org.apache.log4j.Category.error (Category.java:302) a com.blah.MessageProcessTask.run (MessageProcessTask.java:103) a java.util.concurrent.Executors $ RunnableAdapter.call (Executors.java:441) a java.util.concurrent.FutureTask $ Sync.innerRun (FutureTask / java: 268) a java.util.concurrent.FutureTask.run (FutureTask / java: 54) a java.util.concurrent.ThreadPoolExecutor $ Worker.runTask (ThreadPoolExecutor.java:885) a java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:907) a java.lang.Thread.run (Thread.java:619)
" piscina-2-thread-78 quot &; Id = 148 RUNNABLE at java.io.FileOutputStream.writeBytes (Native Metodo) a java.io.FileOutputStream.write (FileOutputStream.java:260) a java.io.BufferedOutputStream.write (BufferedOutputStream.java:105) - bloccato < 0x6f314ba4 > (a java.io.BufferedOutputStream) a java.io.PrintStream.write (PrintStream.java:430) - bloccato < 0xd5d3504 > (a java.io.PrintStream) a org.apache.log4j.ConsoleAppender $ SystemOutStream.write (ConsoleAppender.java:173) a sun.nio.cs.StreamEncoder.writeBytes (StreamEncoder.java:202) a sun.nio.cs.StreamEncoder.implFlushBuffer (StreamEncoder.java:272) a sun.nio.cs.StreamEncoder.implFlush (StreamEncoder.java:276) a sun.nio.cs.StreamEncoder.flush (StreamEncoder.java:122) - bloccato < 0x6243a076 > (a java.io.OutputStreamWriter) a java.io.OutputStreamWriter.flush (OutputStreamWriter.java:212) a org.apache.log4j.helpers.QuietWriter.flush (QuietWriter.java:57) a org.apache.log4j.WriterAppender.subAppend (WriterAppender.java:315) a org.apache.log4j.WriterAppender.append (WriterAppender.java:159) a org.apache.log4j.AppenderSkeleton.doAppend (AppenderSkeleton.java:230) - bloccato < 0x45dbd560 > (a org.apache.log4j.ConsoleAppender) a org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders (AppenderAttachableImpl.java:65) a org.apache.log4j.Category.callAppenders (Category.java:203) - bloccato < 0x6c3ba437 > (a org.apache.log4j.spi.RootLogger) a org.apache.log4j.Category.forcedLog (Category.java:388) a org.apache.log4j.Category.error (Category.java:302) a com.blah.MessageProcessTask.run (MessageProcessTask.java:103) a java.util.concurrent.Executors $ RunnableAdapter.call (Executors.java:441) a java.util.concurrent.FutureTask $ Sync.innerRun (FutureTask / java: 268) a java.util.concurrent.FutureTask.run (FutureTask / java: 54) a java.util.concurrent.ThreadPoolExecutor $ Worker.runTask (ThreadPoolExecutor.java:885) a java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:907) a java.lang.Thread.run (Thread.java:619)
Soluzione
È possibile utilizzare AsyncAppender per staccare meglio il logger dalle appendici.
Su Windows, se fai clic nella finestra della console, la console verrà messa in pausa, ad es. il buffer stdout si riempirà e man mano che l'appender della console scrive in serie, l'applicazione si bloccherà fino al rilascio della console (premere invio o giù di lì).
Prendi in considerazione l'utilizzo di AsyncAppender con log4j - la maggior parte delle volte è una buona idea - l'unico problema è che - il buffer di AsynAppender non viene scaricato completamente all'uscita.
Altri suggerimenti
in primo luogo, credo che log4j scriva sui file e sulla console in serie, altrimenti tutti i log verrebbero danneggiati. quindi mentre un thread sta scrivendo un altro thread che vuole scrivere deve aspettare fino a quando l'altro thread è finito. inoltre, stdout può bloccare se tutto ciò che è attaccato all'altra estremità non lo sta esaurendo.
in unix c'è un descrittore di file speciale chiamato stdout. quando avvii le applicazioni nella console, lo stdout verrà collegato alla console. puoi anche reindirizzare stdout ad altri file. es: java Blah > / Dev / null. è probabile che stdout indichi un file che si sta riempiendo. per esempio, una pipe è un file e se il programma all'altra estremità non sta svuotando la pipe, alla fine il programma che sta scrivendo sulla pipe si bloccherà.