web-dev-qa-db-ja.com

多くのクライアント接続の場合、Nettyスレッドモデルはどのように機能しますか?

私は次のプロジェクトでNettyを使用するつもりです。このプロジェクトは、クライアントとサーバーの両方として機能します。特に、さまざまなサーバーへの多くの接続を確立および維持すると同時に、独自のクライアントにサービスを提供します。

NioServerSocketChannelFactory のドキュメントでは、サーバー側のスレッドモデルをかなり適切に指定しています。バインドされた各リッスンポートには、専用のbossスレッドが必要です。プロセスは、接続されたクライアントがworkerスレッドで非ブロッキング方式で処理されます。具体的には、1つのワーカースレッドが複数の接続されたクライアントを処理できます。

ただし、 NioClientSocketChannelFactory のドキュメントはそれほど限定的ではありません。これはbossworkerスレッドの両方を利用しているようです。ただし、ドキュメントには次のように記載されています。

1つのNioClientSocketChannelFactoryには1つのボススレッドがあります。要求に応じて接続を試みます。接続の試行が成功すると、ボススレッドは接続されたチャネルをNioClientSocketChannelFactoryが管理するワーカースレッドの1つに渡します。

ワーカースレッドもサーバーの場合と同じように機能するようです。

私の質問は、これは私のプログラムから外部サーバーへの接続ごとに1つの専用bossスレッドがあることを意味しますか?このような接続を数百または数千確立した場合、これはどのように拡張されますか?

補足として。単一のエグゼキューター(キャッシュスレッドプール)をbossExecutorworkerExecutorの両方として再利用することによる悪影響はありますか? ChannelFactory?異なるクライアントやサーバーのChannelFactoryインスタンス間での再利用についてはどうですか? これについては、ここで多少説明します ですが、それらの答えは十分具体的ではありません。誰もこれについて詳しく説明できますか?

28
Jiddo

これは、Nettyクライアントスレッドモデルがどのように機能するかに関する質問に対する実際の回答ではありません。ただし、同じNioClientSocketChannelFactoryを使用して、複数のClientBootstrapsを持つ単一のChannelPipelineFactoryを作成し、多数の接続を作成できます。以下の例を見てください。

public static void main(String[] args)
{
    String Host = "localhost";
    int port = 8090;
    ChannelFactory factory = new NioClientSocketChannelFactory(Executors
            .newCachedThreadPool(), Executors.newCachedThreadPool());
    MyHandler handler1 = new MyHandler();
    PipelineFactory factory1 = new PipelineFactory(handler1);
    AnotherHandler handler2 = new AnotherHandler();
    PipelineFactory factory2 = new PipelineFactory(handler2);
    ClientBootstrap bootstrap = new ClientBootstrap(factory);
    // At client side option is tcpNoDelay and at server child.tcpNoDelay
    bootstrap.setOption("tcpNoDelay", true);
    bootstrap.setOption("keepAlive", true);
    for (int i = 1; i<=50;i++){
        if(i%2==0){
            bootstrap.setPipelineFactory(factory1);
        }else{
            bootstrap.setPipelineFactory(factory2);
        }

        ChannelFuture future = bootstrap.connect(new InetSocketAddress(Host,
                port));

        future.addListener(new ChannelFutureListener()
        {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception
            {
                future.getChannel().write("SUCCESS");
            }
        });
    }
}

また、さまざまなパイプラインファクトリをさまざまな接続に設定する方法も示しているため、作成した接続に基づいて、チャネルパイプラインでエンコーダー/デコーダーを微調整できます。

13
Abe

あなたの質問が答えになったかどうかはわかりません。これが私の答えです:アプリのすべての保留中のCONNECTを同時に管理している単一のBossスレッドがあります。 nioを使用して現在のすべての接続を1つの(ボス)スレッドで処理し、正常に接続された各チャネルをいずれかのワーカーに渡します。

1
jpayne

あなたの質問は主にパフォーマンスに関するものです。シングルスレッドは、クライアント上で非常によく拡張されます。

ああ、そしてへまは閉じられました。まだアーカイブを閲覧できます。

0