8

並行スレッド環境内で http 要求を行うために、Netty HTTP クライアント コードの例に取り組んでいます。

ただし、私のシステムはかなり低いスループットで完全に (多くの例外を除いて) 壊れます。

ほぼ擬似コードで:

ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory()) 
bootstrap.setPipelineFactory(new HttpClientPipelineFactory());

ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
Channel channel = future.awaitUninterruptibly().getChannel();

HttpRequest request = new DefaultHttpRequest();
channel.write(request);

この例では、リクエストを作成するために ClientBootstrap を作成し、そこから (いくつかのフープを介して) HTTPRequest を書き込むチャネルを作成します。

これはすべて機能し、良好です。

ただし、同時の状況では、すべてのリクエストが同じフープを通過する必要がありますか? それが現時点で私にとって物事を壊していると思います。接続を再利用するか、まったく別の方法でクライアントを構築する必要がありますか?

また、違いがある場合は、Clojureでこれを行っています。

4

2 に答える 2

7

いいえ、あなたは正しいことをしています。ただし、Channelインスタンスへの参照は保持する必要があります。そのチャネルを取得したら、それが開いている限り、別のブートストラップを作成する必要はありません。(それがあなたがしていることなら。)

これは私が最近のプロジェクトで使用したものです:

クラス ClientConnection (コンストラクター)

// Configure the client.
bootstrap = new ClientBootstrap(
    new NioClientSocketChannelFactory(
        Executors.newCachedThreadPool(),
        Executors.newCachedThreadPool()
    )
);

// Set up the pipeline factory.
bootstrap.setPipelineFactory(
    new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() throws Exception {
            return Channels.pipeline(
                // put your handlers here
            );
        }
    }
);

class ClientConnection.connect(String ホスト, int ポート)

if (isConnected()) {
    throw new IllegalStateException("already connected");
}

// Start the connection attempt.
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));

channel = future.awaitUninterruptibly().getChannel();

// Wait until the connection is closed or the connection attempt fails.
channel.getCloseFuture().addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) throws Exception {
        new Thread(new Runnable() {
            public void run() {
                // Shut down thread pools to exit
                // (cannot be executed in the same thread pool!
                bootstrap.releaseExternalResources();

                LOG.log(Level.INFO, "Shutting down");
            }
        }).start();
    }
});

したがって、基本的には と への参照のみを保持しますbootstrapchannel、前者はこれらのコード行以外ではほとんど使用されません。

注:bootstrap.releaseExternalResources();アプリケーションの終了時に一度だけ実行する必要があります。私の場合、クライアントはいくつかのファイルを送信し、チャネルを閉じて終了します。

接続されたChannelインスタンスを取得したら、再度閉じるまでそのインスタンスを使用するだけで済みます。閉じたら、 を呼び出してbootstrap新しいものChannelを再度作成できます。

個人的には、最初は Netty を理解するのが少し難しいと思いますが、それがどのように機能するかを理解すると、Netty は Java で最高の NIO フレームワークです。IMO。

于 2011-03-31T04:00:48.007 に答える