2

大量の小さなリクエストを持つ HTTP サービスがあり、それらのほとんどは 1 回だけリクエストされます (約 70%)

そのため、リクエストが来たときにチャネルを開いたままにしておくと、すぐに何もせずに多くのチャネルがメモリに残ります。

現在行っていることは、IdleStateHandler と IdleStateAwareChannelHandler を登録することです。これにより、5 秒間アクティビティがないチャネルはすべて閉じられます。

これは機能しているようで、開いているチャネルのサイズは安定しています。

しかし、別の問題があります。

開いているチャネルごとに、現在のチャネルに関連するいくつかの有用な情報を保存するために、それに関連付けられたカスタムの ServerConnection オブジェクトがあります。これらの ServerConnection を、connectionMap というグローバル マップに保持します。キーはチャネルです。

messageReceived が呼び出されるたびに、チャネルがすでに connectionMap にあるかどうかを確認します。ない場合は、新しい ServerConnection が作成されます。

channelClosed/exceptionCaught イベントが検出されるたびに、connectionMap.remove を呼び出して削除します。

そして、IdleStateHandler が呼び出されたときに手動でマップから削除します。

ただし、ServerConnections の一部は削除されませんが、Channel の状態は実際には閉じられています。

何か見逃しましたか?チャネルが閉じられているのに、イベントをキャッチするのを忘れている場所は他にありますか?

4

1 に答える 1

4

ChannelFutureListenerインターフェースを使用してチャンネルの近い将来に登録することで、チャンネルが閉じたときに通知を受け取ることができます。

class MyClass implements ChannelFutureListener
{
    // Whatever stuff this class also does 
    // ...

    public void operationComplete(ChannelFuture future) throws Exception
    {
        System.out.println("This channel closed! " + 
                           future.getChannel().getId().toString());
    }

}

次に、あなたのチャンネルのためにあなたは...

channel.getCloseFuture().addListener(instanceOfMyClass); 

チャンネルが閉じると、ChannelFutureListener通知が届きます。

これはNetty3.xであることに注意してください。Netty 4.xは、調整する必要のないいくつかの点でメソッド名を変更しました(getゲッターからプレフィックスを削除しました)。

于 2013-01-09T03:41:57.587 に答える