Tomcat NIOコネクタの内部を知りたいです。 CometProcessorを実装するサーブレットを作成するとき、スレッドはどのくらい正確に使用されますか?接続ごとに1つのスレッドですか?
私が読んだものから、会話はこのようになります
クライアントはサーブレットに接続します
接続されたクライアントがデータを利用できるようになるまで、サーブレットは接続を維持します
データの準備ができると、サーバーはhttpResponseに書き込み、フラッシュします。これは実際に接続を切断しますか?
クライアントは、サーバーが再びハングアップする別の要求を送信します。
これが発生し続ける場合、いくつのスレッドが使用されますか?
NIOとCometは完全に無関係です。それらを組み合わせて使用できます。
NIO(またはAPR)コネクタを使用すると、スレッドモデルにより、より少ないスレッドでより多くのリクエストを処理できます。コネクタ間の比較については、 http://Tomcat.Apache.org/Tomcat-7.0-doc/config/http.html#Connector_Comparison を参照してください。
Comet(およびWebsocket)にはまったく異なるディスパッチモデルがあり、異なるアプリケーションアーキテクチャを必要とし、異なる方法でより高いスループットを実現します。
質問で提起するシナリオは、典型的なブロッキング1スレッド/リクエストモデルです。ステップ4では、Java BIOコネクター(Tomcat 7までのデフォルト))は、キープアライブHTTPリクエストのために、既存のコネクターでの追加リクエストを待ち続けます。前のリクエストでConnection:close
を設定し、接続を閉じない場合、キープアライブタイムアウトに達するまでスレッドはハングします。NIOコネクタを使用する場合、応答が送信された直後にスレッドはスレッドプールに戻ります到着しないキープアライブリクエストのスレッドを「無駄にする」ことはありません。
Comet/Websocketは、特別に作成されたサーブレット(およびオプションのフィルター)にメッセージを配信することでまったく異なる動作をし、スレッドは送信するメッセージまたは書き込まれるデータがある場合にのみ使用されます。
UPDATE 2016-08-19
Tomcat 8.5および9.0は、BIOコネクタを完全に削除しました。これは、多くの新しいAPIとテクノロジー(Websocketなど)がノンブロッキングセマンティクスを必要とし、ブロッキングAPIの上にノンブロッキングサービスを構築することが非常に難しいためです。ジョブを完了するために必要なコードは、Tomcatコードの残りの部分を非常に見苦しくするなどであったため、BIOコネクタを完全に削除するという決定が下されました。そのため、Tomcat 8.5以降では、NIO、NIO2、およびAPRベースのコネクタのみが使用可能です。
Tomcat 8.5および9.0でも、Cometのサポートが廃止されたことに注意してください。 Cometの使用はすべて、より標準的なプロトコルであるWebsocketに置き換える必要があります。
NIOが使用するスレッドが少ないため、tcp/ipポートの使用が少なくなります。
ポートは1〜65534であることがわかっているため、NIOはBIOよりも高いTPS(Transactions Per Second)に到達できると言えます。
両方のプロトコルをテストしました:HTTP/1.1
およびorg.Apache.coyote.http11.Http11NioProtocol
同じWebプロジェクト、同じホスト、および同じserver.xmlを使用しますが、プロトコルは同じです。
テストにはjmeterを使用します。
数分でHTTP/1.1、ホスト使用ポートが30000を超え、TPSが300のみの場合、要求を実行するように1000スレッドを設定します!
Org.Apache.coyote.http11.Http11NioProtocolの場合、使用ポートの最大数が3000を超えることはなく、TPSは1200を超えます!
この議論に遅れて追加-ブロッキングIOと非同期NIOのパフォーマンス比較のコンテキストでは、優れた読み取りは "サーバーの古い書き込み方法" です。接続モデルごとのスレッドの下の要約は、一般的な信念に反して、NIOバージョンと比較してパフォーマンスが良く、記述しやすいことがわかりました。
TomcatのBIO(リクエスト処理はスレッドを受け入れるようにバインドされている)とNIO(リクエスト処理は別のワーカースレッドに渡される)の違いを検討するのに役立つNIOコネクタに関する2つの良い記事を次に示します。