2012-11-11 8 views
26

すでに似たような質問がありましたが、それを削除しましたが、修正したと思っていましたが間違っていました。Play framework/Nettyがソケットを解放しない

私は、自分のWebプロジェクトの1つとして、本番環境でPlayフレームワークを使用しています。時々、Playはメインページをレンダリングせず、静的コンテンツファイルの一部を返さない。

最初のスクリーンショットは、firebug consoleを表示しています。ホームページを表示すると、最初にサイトの読み込みが固執します。 enter image description here 2つ目のスクリーンショットでは、2つの静的リソースがロードされていないときにコンソールが表示されます。

enter image description here

最初のアプリケーションは、それが5-7日のために働くために、私はこの問題を見ることができている、細かい動作します。それは再現するのは難しいです、それは15回起こります、私はキャッシュデータを削除し、ページをリロードする必要があります。 (FFでCRTL-F5を押す)。問題は、異なるマシンやOSのブラウザのほとんどで再現できます。最初は、ホスティングプロバイダにいくつかの問題があると考えていました。しかし、私はそれを変更し、問題はなくなっていません。

プレイのバージョンは1.2.5です。 1.2.2も試しました。 PlayはCentOS-5-32ビットのスタンドアロンサーバーとして動作しています。

私は、Playフレームワークで使用されているNettyにいくつかの問題があると思われます。 Netty 3.5.7の最終ジャーはPlayで使用されています。開いたファイル記述子の数日間

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

数は、後に平均初めにウェブサイトへの負荷とが同じであることを、140から350のノートに成長します。

多くのソケットがプロセスによってオープンされていますが、これは後でリリースされません。アプリケーションの起動時に開かれたTCP接続の

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] 

更新

数(ランニングの数時間)が開いているTCPの実行中、数の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 

2日後です接続は490です。

[[email protected] 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 

このすべてが開いているT CP接続はhttp接続(データベースでも他の接続でもない)です。ウェブサイトの平均負荷は常に同じですが、開いているファイルディスクリプタとオープンソケットの数は常に増加しています。too many open files exception

最初にアプリケーションは9-15の新しいI/Oスレッド(Nettyワーカー)で開始されます。すべてのNettyスレッドは、ほとんどの場合実行状態です。そして〜16はWait状態のスレッドを再生します。

Nettyの従業員の数が27人になった後、私はNettyの専門家ではなく、正常な動作であるかどうかはわかりません。

デッドロックが発生したスレッドはほとんどありません。1スレッドを再生し、Nettyスレッドを1つ再生しました。また、最初のPlayスレッドによってロックされる別のPlayスレッドがあります。合計で3つのロックされたスレッド。私は、このデッドロックが問題の根本的な原因ではないことを、確信しているが、根本的な原因は同じ

Name: New I/O worker #21 
State: BLOCKED on [email protected] 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 [email protected] 
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) 

第二のスレッドになります

Name: play-thread-2 
State: BLOCKED on [email protected] 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 [email protected] 
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) 

更新

I Tomcat 7と同じ環境に同じPlayアプリケーションをデプロイしました.24時間が経過し、問題はなくなりました。開かれたTCP接続の数は一定のままです。開いているファイル記述子の数が〜70を超えていません。これは、同じプロダクションホスト、同じデータベース、およびアプリケーションの同じユーザーです。

+3

リクエストはPlayアプリケーションに直接当たっているのですか、プロキシ(Apacheなど)を経由していますか? –

+0

プロキシを使用していないため、リクエストは直接Play – Anton

+1

に行きます。サーバー側でスレッドダンプを実行しましたか?サーバー上に何かがハングしていて、スレッドを再利用できませんでした。 –

答えて

1

私は実際にはプレイ中ではなく、実行中のJVMに似たバグが発生しました。ファイルハンドルを指しているクローズドチャネルは、強制的にJVMを閉じる​​まで解放されません。悲しいかな、私はバグレポートを見つけたか、それともリンクしているのかは分かりませんが、JVMの既知のバグです。私はそれを回避する必要があった。私が提案できる最も良いことは、できるだけ同じチャンネル/ファイルハンドルを使用するようにコードを書き直すことです。

+0

これはどんな種類のJava Web Appにも影響するとは思われませんが、これは私たちが定期的に見ている問題ではありません。 – sorencito

1

ChunkedWriteHandlerにデッドロックに関する問題がいくつかありました。それらのすべてはあなたのNettyバージョンで解決されるようです。とにかく、そのコードがこの種の問題を引きつけているようです。私はあなたがNettyの人に問題を提出することをお勧めします。

https://issues.jboss.org/browse/NETTY-384

また、そのクラスに関するあったどのように多くの課題のアイデアを得るために、「同様の問題」を参照してください。

関連する問題