Log4j está bloqueando mi aplicación, ¿qué estoy haciendo mal?
-
10-07-2019 - |
Pregunta
Primero algunos antecedentes sobre la aplicación. Tengo una aplicación que procesa muchas tareas independientes en paralelo a través de un grupo de subprocesos. El grupo de subprocesos ahora está colgando.
El siguiente es un fragmento de mis volcados de subprocesos, todos mis subprocesos en el grupo 2 están BLOQUEADOS por " pool-2-thread-78 " ;. Parece estar bloqueado tratando de escribir en la consola, lo que me parece extremadamente extraño. ¿Alguien puede arrojar alguna luz sobre la situación para mí?
EDITAR : Detalles de la plataforma versión de Java " 1.6.0_07 " Java (TM) SE Runtime Environment (compilación 1.6.0_07-b06) VM de cliente Java HotSpot (TM) (compilación 10.0-b23, modo mixto, uso compartido)
Servidor Ubuntu Linux máquina dual quad core.
Parece que se bloquea al escribir en el flujo de impresión, he considerado simplemente quitar el apéndice de la consola, sin embargo, prefiero saber por qué está bloqueando y eliminarlo en base a este conocimiento. En el pasado, la eliminación y ver si funciona ha vuelto a morderme :)
sección relevante de mi log4j
log4j.rootLogger = DEBUG, STDOUT log4j.logger.com.blah = INFORMACIÓN, REGISTRO log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender log4j.appender.LOG = org.apache.log4j.FileAppender
Extracto de volcado de subprocesos
" pool-2-thread-79 " Id = 149 BLOQUEADO en org.apache.log4j.spi.RootLogger@6c3ba437 propiedad de " pool-2-thread-78 " Id = 148 en 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)
" pool-2-thread-78 " Id = 148 RUNNABLE en java.io.FileOutputStream.writeBytes (Native Método) en java.io.FileOutputStream.write (FileOutputStream.java:260) a java.io.BufferedOutputStream.write (BufferedOutputStream.java:105) - bloqueado < 0x6f314ba4 > (un java.io.BufferedOutputStream) en java.io.PrintStream.write (PrintStream.java:430) - bloqueado < 0xd5d3504 > (un java.io.PrintStream) en 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) - bloqueado < 0x6243a076 > (un java.io.OutputStreamWriter) en 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) - bloqueado < 0x45dbd560 > (un org.apache.log4j.ConsoleAppender) en org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders (AppenderAttachableImpl.java:65) a org.apache.log4j.Category.callAppenders (Category.java:203) - bloqueado < 0x6c3ba437 > (un org.apache.log4j.spi.RootLogger) en 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)
Solución
Puede usar AsyncAppender para separar mejor el registrador de los anexos.
En Windows, si hace clic en la ventana de la consola, esto detendrá la consola, p. el búfer stdout se llenará y, a medida que el apéndice de la consola escriba en serie, su aplicación se bloqueará hasta que suelte la consola (presione Intro más o menos).
Considere usar AsyncAppender con log4j; la mayoría de las veces es una buena idea, el único problema es que el búfer AsynAppender no se vacía completamente al salir.
Otros consejos
primero, creo que log4j escribe en los archivos y en la consola en serie o de lo contrario todos sus registros estarían dañados. entonces, mientras un hilo está escribiendo, otro hilo que quiere escribir tiene que esperar hasta que el otro termine. Además, stdout puede bloquearse si lo que está conectado al otro extremo no lo está drenando.
en unix hay un descriptor de archivo especial llamado stdout. cuando inicie aplicaciones en la consola, stdout se adjuntará a la consola. También puede redirigir stdout a otros archivos. ex: java Blah > / dev / null. es probable que tenga stdout apuntando a un archivo que se está llenando. por ejemplo, una tubería es un archivo y si el programa en el otro extremo no está drenando la tubería, entonces el programa que está escribiendo en la tubería eventualmente se bloqueará.