0

TCP/IP の上にバイナリ プロトコルを実装し、Netty を使用してこれを実現しています。私の問題は、パフォーマンスがかなり悪いことです (600 msg/s)。クライアントとして、1 つの接続のみでサーバーに接続しています。JTop で実行中のインスタンスを調べたところ、Netty が 1 つのワーカー スレッドを非常に頻繁に使用しており、他の 5 つのワーカー スレッドは何もしていない (0% の使用量) ことがわかりました。私は Web を掘り下げていましたが、見つかったのは ExecutionHandler についての言及だけです。しかし、これらの 6 つのワーカー スレッドで十分な場合、なぜこれを使用する必要があるのでしょうか。それとも、Netty がこれらのスレッドを使用する方法を誤解していますか?

私のNetty初期化コード:

this.channelFactory = new NioClientSocketChannelFactory(this.executors, DaemonExecutors.newCachedDaemonThreadPool(), 1, 6);
this.clientBootstrap = new ClientBootstrap(channelFactory);
this.channelGroupHandler = new ClientChannelGroupHandler(this.channels);
this.clientBootstrap.getPipeline().addLast("ChannelGroupHandler", this.channelGroupHandler);

ヒントをありがとう

4

2 に答える 2

2

NIO、または NIO のノンブロッキング バージョン (「新しい」I/O) を使用すると、読み取り/書き込み操作でスレッドがブロックされない (名前の由来) ため、単一のスレッドを複数の接続に使用できます。I/O をブロックすると、異なる接続間のトラフィックを処理できなくなるため、接続ごとにスレッドが必要になります。

これにより、スレッドのオーバーヘッドがなくなるため、より効率的な通信を実行できます。

きちんとしたチュートリアルがここにあります(元の Oracle チュートリアルは、Google の顔から消えてしまったようです)。

于 2013-11-11T13:10:11.937 に答える
0

ワーカー スレッドが 1 つしか使用されていないのは、サーバーへの接続が 1 つしかないためです。複数の接続を作成した場合、より多くのワーカー スレッドが使用されます。

各接続の作業が並列化に適している場合は、内部でスレッドを使用するハンドラーを実装できますが、Netty はそれを行いません。

NIO/OIO の違いについて言えば、NIO の考え方は、複数の接続のイベントを 1 つのスレッドで処理することです。ただし、これは 1 つのスレッドがすべての作業を処理するという意味ではありません。「単一スレッド」は、作業を他の (ワーカー) スレッドにディスパッチするだけです。

以下は、Netty doc からの抜粋です。

スレッドの仕組み NioServerSocketChannelFactory には 2 種類のスレッドがあります。1 つはボス スレッドで、もう 1 つはワーカー スレッドです。

ボス スレッド バインドされた各 ServerSocketChannel には、独自のボス スレッドがあります。たとえば、80 と 443 などの 2 つのサーバー ポートを開いた場合、2 つのボス スレッドが作成されます。ボス スレッドは、ポートのバインドが解除されるまで着信接続を受け入れます。接続が正常に受け入れられると、ボス スレッドは受け入れられたチャネルを NioServerSocketChannelFactory が管理するワーカー スレッドの 1 つに渡します。

ワーカー スレッド 1 つの NioServerSocketChannelFactory は、1 つ以上のワーカー スレッドを持つことができます。ワーカー スレッドは、非ブロッキング モードで 1 つ以上のチャネルに対して非ブロッキングの読み取りと書き込みを実行します。

于 2013-11-11T14:04:07.040 に答える