starter play new framework playframework netty nio playframework-1.x file-descriptor

playframework - new - Play framework/Netty no libera socket



scala play documentation (2)

Ya hice una pregunta similar, pero la borré, ya que pensé que la arreglé, pero estaba equivocada.

Estoy usando Play Framework en producción para uno de mis proyectos web. De vez en cuando, Play no muestra la página principal o no devuelve algunos de los archivos de contenido estático.

La primera captura de pantalla muestra la consola Firebug, la carga del sitio se atasca al principio, cuando se sirve la página de inicio. La segunda captura de pantalla muestra la consola fiddler, cuando no se cargan 2 recursos estáticos.

Inicialmente, la aplicación funciona bien, tiene que funcionar durante 5-7 días y puedo ver este problema. Es difícil de reproducir, sucede 1 de 15 veces, tengo que eliminar datos de caché y volver a cargar la página. (presionando CRTL-F5 en FF). El problema se puede reproducir en la mayoría de los navegadores de diferentes máquinas y sistemas operativos. Inicialmente, estaba pensando que hay algunos problemas con el proveedor de alojamiento. Pero lo he cambiado y el tema no se ha ido.

La versión de la obra es 1.2.5. Trató 1.2.2 también. El juego se ejecuta como servidor independiente en CentOS-5-32 bits.

Sospecho que hay algunos problemas con Netty que son usados ​​por Play Framework. El tarro final de Netty 3.5.7 es utilizado por Play.

cd /proc/28761/fd ls -l | wc -l 337

Durante algunos días, el número de descriptor de archivo abierto crece de 140 a 350. Tenga en cuenta que la carga promedio para el sitio web al principio y después es la misma.

Puedo ver muchos sockets abiertos por proceso, que no se lanzan más adelante.

lrwx------ 1 root root 64 Nov 11 10:34 300 -> socket:[1079566] lrwx------ 1 root root 64 Nov 11 10:34 301 -> socket:[1079568] lrwx------ 1 root root 64 Nov 11 10:34 302 -> socket:[1149958] lrwx------ 1 root root 64 Nov 11 10:34 303 -> socket:[1160807] lrwx------ 1 root root 64 Nov 11 10:34 304 -> socket:[1160605] lrwx------ 1 root root 64 Nov 11 10:34 305 -> socket:[1157435] lrwx------ 1 root root 64 Nov 11 10:34 306 -> socket:[1160607] lrwx------ 1 root root 64 Nov 11 10:34 307 -> socket:[1160609] lrwx------ 1 root root 64 Nov 11 10:34 308 -> socket:[1155542] lrwx------ 1 root root 64 Nov 11 10:34 309 -> socket:[1120231]

Actualizar

El número de conexiones TCP abiertas al inicio de la aplicación (pocas horas de ejecución) es de 63.

Total: 150 (kernel 181) TCP: 63 (estab 38, closed 5, orphaned 0, synrecv 0, timewait 3/0), ports 44 Transport Total IP IPv6 * 181 - - RAW 0 0 0 UDP 7 4 3 TCP 58 9 49 INET 65 13 52 FRAG 0 0 0

Después de 2 días de funcionamiento, el número de conexiones TCP abiertas es 490.

[root@82711-2 fd]# ss -s Total: 459 (kernel 490) TCP: 378 (estab 271, closed 23, orphaned 0, synrecv 0, timewait 9/0), ports 37 Transport Total IP IPv6 * 490 - - RAW 0 0 0 UDP 7 4 3 TCP 355 12 343 INET 362 16 346 FRAG 0 0 0

Toda esta conexión TCP abierta es una conexión http (no la base de datos o cualquier otra). La carga promedio en el sitio web es la misma todo el tiempo, pero el número de descriptores de archivos abiertos y sockets abiertos aumenta todo el tiempo hasta que se too many open files exception

Inicialmente, la aplicación se inicia con 9-15 hilos de E / S nuevos (trabajadores de Netty). Todos los subprocesos de Netty están en estado de ejecución la mayor parte del tiempo. Y ~ 16 hilos de juego que están en estado de espera.

Después de unos días de trabajo, el número de trabajadores de Netty se convirtió en 27. No soy un experto en Netty, no estoy seguro de si es un comportamiento normal.

Pocos hilos quedaron en punto muerto: 1 hilo de juego y 1 hilo de Netty. También hay otro hilo de reproducción que está bloqueado por el primer hilo de reproducción. Así que 3 hilos bloqueados en total. Estoy seguro de que estos puntos muertos no son la causa raíz del problema, pero la causa raíz puede ser la misma

Name: New I/O worker #21 State: BLOCKED on org.jboss.netty.handler.stream.ChunkedWriteHandler@15e057 owned by: play-thread-2 Total blocked: 44 Total waited: 9 Stack trace: org.jboss.netty.handler.stream.ChunkedWriteHandler.flush(ChunkedWriteHandler.java:188) org.jboss.netty.handler.stream.ChunkedWriteHandler.handleUpstream(ChunkedWriteHandler.java:140) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:792) org.jboss.netty.channel.SimpleChannelUpstreamHandler.channelClosed(SimpleChannelUpstreamHandler.java:212) org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:93) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:792) org.jboss.netty.handler.codec.replay.ReplayingDecoder.cleanup(ReplayingDecoder.java:636) org.jboss.netty.handler.codec.replay.ReplayingDecoder.channelClosed(ReplayingDecoder.java:533) org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:93) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559) org.jboss.netty.channel.Channels.fireChannelClosed(Channels.java:476) org.jboss.netty.channel.socket.nio.AbstractNioWorker.close(AbstractNioWorker.java:631) org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:109) org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:66) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendDownstream(DefaultChannelPipeline.java:780) org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:55) org.jboss.netty.channel.DefaultChannelPipeline.sendDownstream(DefaultChannelPipeline.java:591) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendDownstream(DefaultChannelPipeline.java:785) org.jboss.netty.handler.stream.ChunkedWriteHandler.handleDownstream(ChunkedWriteHandler.java:111) org.jboss.netty.channel.DefaultChannelPipeline.sendDownstream(DefaultChannelPipeline.java:591) org.jboss.netty.channel.DefaultChannelPipeline.sendDownstream(DefaultChannelPipeline.java:582) org.jboss.netty.channel.Channels.close(Channels.java:821) org.jboss.netty.channel.AbstractChannel.close(AbstractChannel.java:194) org.jboss.netty.channel.ChannelFutureListener$1.operationComplete(ChannelFutureListener.java:41) org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultChannelFuture.java:399) org.jboss.netty.channel.DefaultChannelFuture.notifyListeners(DefaultChannelFuture.java:385) org.jboss.netty.channel.DefaultChannelFuture.setSuccess(DefaultChannelFuture.java:334) org.jboss.netty.channel.socket.nio.AbstractNioWorker.write0(AbstractNioWorker.java:493) - locked java.lang.Object@3b7e28 org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromTaskLoop(AbstractNioWorker.java:431) org.jboss.netty.channel.socket.nio.AbstractNioChannel$WriteTask.run(AbstractNioChannel.java:364) org.jboss.netty.channel.socket.nio.AbstractNioWorker.processWriteTaskQueue(AbstractNioWorker.java:349) org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:245) org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:38) org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:102) org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) java.lang.Thread.run(Thread.java:662)

Segundo hilo:

Name: play-thread-2 State: BLOCKED on java.lang.Object@3b7e28 owned by: New I/O worker #21 Total blocked: 23 Total waited: 34 778 Stack trace: org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:654) org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:408) org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:127) org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:66) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendDownstream(DefaultChannelPipeline.java:780) org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:63) org.jboss.netty.channel.DefaultChannelPipeline.sendDownstream(DefaultChannelPipeline.java:591) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendDownstream(DefaultChannelPipeline.java:785) org.jboss.netty.channel.Channels.write(Channels.java:733) org.jboss.netty.handler.stream.ChunkedWriteHandler.flush(ChunkedWriteHandler.java:262) - locked org.jboss.netty.handler.stream.ChunkedWriteHandler@15e057 org.jboss.netty.handler.stream.ChunkedWriteHandler.handleDownstream(ChunkedWriteHandler.java:121) org.jboss.netty.channel.DefaultChannelPipeline.sendDownstream(DefaultChannelPipeline.java:591) org.jboss.netty.channel.DefaultChannelPipeline.sendDownstream(DefaultChannelPipeline.java:582) org.jboss.netty.channel.Channels.write(Channels.java:712) org.jboss.netty.channel.Channels.write(Channels.java:679) org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245) play.server.PlayHandler.serveStatic(PlayHandler.java:886) play.server.PlayHandler$NettyInvocation.init(PlayHandler.java:182) play.Invoker$Invocation.run(Invoker.java:276) play.server.PlayHandler$NettyInvocation.run(PlayHandler.java:229) java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) java.util.concurrent.FutureTask.run(FutureTask.java:138) java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98) java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206) java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) java.lang.Thread.run(Thread.java:662)

Actualizar

Desplegué la misma aplicación Play en el mismo entorno de Tomcat 7. Pasaron 24 horas y el problema desapareció, la cantidad de conexiones TCP abiertas permanece constante. El número de descriptores de archivos abiertos no supera ~ 70. Se trata de los mismos hosts de producción, la misma base de datos y los mismos usuarios de la aplicación.


De hecho, me encontré con un error similar que no estaba en juego, pero en la JVM (en la que se ejecuta la reproducción), los canales cerrados que apuntan a los identificadores de archivos no se liberan hasta que se los obliga a cerrar la JVM. Lamentablemente, no recuerdo cómo encontré el informe de error, o me vincularía a él, pero es un error conocido EN LA JVM. Terminé teniendo que trabajar alrededor de ello. Lo mejor que puedo sugerir es que reescriba su código para usar los mismos canales / manejadores de archivos tanto como sea posible.


Hubo varios problemas con puntos muertos en el ChunkedWriteHandler. Todos ellos parecen estar resueltos en su versión de Netty. De todos modos, ese pedazo de código parece estar atrayendo ese tipo de problemas. Le sugiero que presente un problema para los chicos de Netty.

two

También vea "problemas similares" para tener una idea de cuántos problemas hubo con respecto a esa clase.