前回の投稿から大分空いてしまいました、、、
本日は技術的なトピックを投稿してみます。
Java19になって仮想スレッド(かつてグリーンスレッドと呼ばれていたもの)が使えるようになりました。とはいえまだExperimentalですが。
JVMの起動パラメータに --enable-preview
と付ければ関連APIを実行できるようになります。
(※23-01-10追記) グリーンスレッドとvirtual threadは大きく異なるものでした。 M:Nモデルというモデルです。詳しくはこちら。 https://stackoverflow.com/questions/74639116/what-is-the-difference-between-green-threads-and-virtual-threads
そこで、Tomcatを仮想スレッドで動作させられないか調べてみたら案外簡単に動きました。
まず、このようなクラスを用意します。
package jp.docurain.tomcat; import java.util.concurrent.Executors; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleState; import org.apache.catalina.util.LifecycleMBeanBase; public final class VirtualThreadExecutor extends LifecycleMBeanBase implements org.apache.catalina.Executor { private java.util.concurrent.Executor es; private String name = "tomcat-vt"; private String namePrefix = "tomcat-vt-"; public void setName(final String x) { this.name = x; } @Override public String getName() { return this.name; } public void setNamePrefix(final String x) { this.namePrefix = x; } public String getNamePrefix() { return this.namePrefix; } @Override public void execute(final Runnable command) { this.es.execute(command); } @Override protected String getDomainInternal() { return null; } @Override protected String getObjectNameKeyProperties() { return "type=Executor,name=" + this.getName(); } @Override protected void startInternal() throws LifecycleException { this.es = Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name(this.namePrefix, 0).factory()); this.setState(LifecycleState.STARTING); } @Override protected void stopInternal() throws LifecycleException { this.setState(LifecycleState.STOPPING); } }
次に、このクラスをコンパイルしてjarにして、Tomcatのインストールディレクトリのlibへ放り込みます。
つぎにserver.xmlを以下のようにするだけ。簡単ですね。
<Server port="8005" shutdown="SHUTDOWN"> ...(略) <Service name="Catalina"> <!-- 上記でコンパイルしたクラス --> <Executor name="vthread" className="jp.docurain.tomcat.VirtualThreadExecutor" /> <!-- Executorのnameをexecutorへ指定 --> <Connector executor="vthread" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> </Service> ...(略) </Server>
で、起動して何かリクエストを投げてみると、これまでは
2022-11-27 16:47:32,099 INFO [...] http-nio-8080-exec-1 何かのログ
のようなログだったのが、
2022-11-27 16:47:32,099 INFO [...] tomcat-vt-1 何かのログ
のように変わっています。 起動中のスレッドを見てみても、TomcatのNioコネクター関連のスレッドが一つもありません。というわけで成功したようです。
実際に商用利用可能なレベルなのか、引き続き調査してみます。本日はここまで。