began.2017-09-30UndertowでHttpHandlerを実行するスレッドを切り替えるUndertowUndertow...というかXNIOでは、2種類のスレッドがあります。Threadは、ノンブロッキングなタスクを実行するためのスレッドで、ブロックするような処理をしてはいけません(他の接続への処理が止まる可能性があります)。Threadは、ブロッキングなタスク用のスレッドプールで管理されます。一般に、CPUコア数あたり10スレッドで十分高いはず、という感じのドキュメントになっています。Thread×8です。Threadに切り替える方法が書いてあります。LifecyleHttpServerExchange#exchangeを使いなさい、と。今回、これを試してみましょう。準備まずは、Maven依存関係から。</dependency>簡単な起動クラスを作成します。}}このBuilder#setHandlerに設定するHandlerを、ちょっとずつ変えながら見ていってみましょう。**/)単純なサンプルとりあえず、動かすための簡単なサンプルを書いてみます。Threadかどうか?ブロッキングしているかどうか?を返すようにしてみました。SimpleHttpHandler())確認。Threadで動作しているようです。Threadしかいないようです。Threadに切り替えてみましょう。}}ここでのポイントは、HttpServerExchange#isInIoThreadがtrueの場合、HttpServerExchange#dispatchでHttpHandlerを渡して折り返すことですね。Threadで処理されるようになります。こちらのHttpHandlerを使用するように、Appクラスを修正します。DispatchWorkerHttpHandler())確認してみましょう。falseこの時、HttpHandler側にはhandleRequestの先頭のログが2回出力されることになります。falseHttpServerExchange#isInIoThreadがfalseになり、出てくるスレッド名も変わりましたね。doneスレッドダンプを見てみると、大量のスレッドが出現します。Threadが使われるようになったようです。同じスレッドにdispatchするHttpServerExchange#dispatchには、いくつかオーバーロードされたバージョンがあります。http://undertow.io/javadoc/1.4.x/io/undertow/server/HttpServerExchange.htmljava.util.concurrent.Executorを渡せるdispatchメソッドもあり、Undertowの提供するSameThreadExecutorを使用すると、同じスレッドで処理を続けるようにdispatchすることができます。}}SameThreadExecutorの中身は、単純ですけれど。Threadに切り替えることもできます。Threadにdispatchするという内容になっています。}この場合、dispatchの引数はRunnableとして扱われています。Threadに切り替えるみたいなことができます。}}この場合、HttpServerExchange#getIoThreadを使ってdispatchするところがポイントです。ToIoThreadHttpHandler());Blocking?ところで、ここまでずっとexchange.isBlocking()とかでブロッキングかどうかを見ていたのですが、実はこれ、いつもfalseです。これがtrueを返すようになるには、HttpServerExchange#startBlockingする必要があります。IOHttpServerExchange#startBlockingを使うことで、ブロッキングIOのAPIを使うことができるようになります。UndertowのServlet実装が、これを使っています。Threadに切り替えます、と。ThreadからRead/Writeは禁止されます。https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/UndertowInputStream.java#L83-L85https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/UndertowOutputStream.java#L112-L114このstartBlockingを使う前は、リクエスト/レスポンスへの入出力はAsyncなSender/Receiverが利用されています。https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/server/HttpServerExchange.java#L1306-L1332https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/AsyncSenderImpl.javahttps://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/AsyncReceiverImpl.javastartBlockingすることで、BlockingなSender/Receiverが使われるようになります。https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/BlockingSenderImpl.javahttps://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/BlockingReceiverImpl.javastartBlockingで、HttpServerExchange中にBlockingHttpExchangeへの参照が作られるようになりますよ、と。https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/server/HttpServerExchange.java#L1458-L1492もうちょっとスレッドの管理を見てみようスレッドダンプを取った時に、こんな感じのスレッドがわらわらと現れました。[0x00007f21753db000]これらを、もう少し見てみたいと思います。Threadも含めて、Workerという扱いになっているっぽい...?https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/Undertow.java#L119スレッドの作成は、XNIO側になります。Threadと、Acceptを管理するスレッドが作られるのはNioXnioWorkerのようですね。Threadの管理をしています。Threadに委譲されるのは、現在の接続からXniWorkerが取得でき、そこからexecuteするとhttps://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/server/HttpServerExchange.java#L795XniWorkerが管理しているTaskPoolに突っ込まれるからですね。Threadを直接取得できます。Threadは、WorkerThreadというクラスでした。https://github.com/xnio/xnio/blob/3.3.8.Final/nio-impl/src/main/java/org/xnio/nio/WorkerThread.java#L79これは、XnioIoThreadのサブクラスです。Threadはどうなのか?ふつうのThreadですね。ThreadがThreadでしたね。Threadの切り替えや、スレッドまわりをちょっと追ってみました。前々から少しは気になっていた箇所なのですが、意外と面白かったです。RESTEasyが3.6.0.FinalでR...2018-05-20jcmdメモそろそろいい加減に、jpsから各種のJDK付属のツールからjcmdに...2017-02-11UndertowでWebSocketを使って遊ぶWebSocketを軽く触ってみようと思いまして。読者になる検索リンクはてなブログブログをはじめる週刊はてなブログはてなブログPro月別アーカイブはてなブログをはじめよう!Kazuhiraさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。