Quarkusのスレッドプール設定
Quarkusで実行されるブロッキングタスク(JAX-RS/Servletなど)は、従来のAPサーバと同様にランタイム内部で管理されるスレッドプールにより実行されます。
WildFly/JBoss EAPでtask-max-threadsに相当するパラメータは、ソースコード中のapplication.propertiesにおいてquarkus.thread-pool.max-threads
として設定します。
src/main/resources/application.properties
# スレッドプールのアイドルスレッド数。未設定時のデフォルトは1。 quarkus.thread-pool.core-threads=32 # スレッドプールの最大数。未設定時のデフォルトは論理プロセッサ数x8。 quarkus.thread-pool.max-threads=64
このスレッドの実態はスレッドダンプを取得すると executor-thread-n
として確認できます。
kill -3 <pid> "executor-thread-1" #24 daemon prio=5 os_prio=31 tid=0x00007f966b09b000 nid=0x5c03 waiting on condition [0x00007000112da000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at sample.quarkus.jpajaxrscdijta.Sleeper.sleep(Sleeper.java:7)
スレッドプールのチューニングはQuarkus0.16.1の時点では公式ドキュメントに言及がないですが、ブロッキングタスクを動かすならばチューニングした方が良いです。
- デフォルト値が小さい。WildFlyではtask-max-threadsは論理プロセッサ数 x 16ですが、Quarkus0.16.1では論理プロセッサ数 x 8です。JDBCによるブロッキングI/O待ちですぐに枯渇します。
- dockerの
--cpuset-cpus=0
など、コンテナレイヤで論理プロセッサ数を絞っている場合は、絞られたCPU数 x 8になる。- Quarkusの実装ではLinux環境の場合はコア数算出にRuntime.availableProcessor()依存せず、/proc/self/statusのCpus_allowedの値からコア数算出するorg.wildfly.common.cpu.ProcessorInfoクラスを使っているため、Java8のマイナーバージョンに関わらずcgroupsが反映されます。