iku8blog

Webエンジニアのタダのメモ。

SpringBootでのhttpスレッド数の指定と確認と検証を行う

f:id:iku8:20210526131317p:plain SpringBootでスレッド数を指定して、正しく指定できているかの確認と、正常にリクエストがスレッドによって正しく処理されているかの検証を行う。

application.propertiesでのスレッド数の指定

※yamlの場合は置き換えてください。

server.tomcat.threads.max=100
server.tomcat.threads.min-spare=100

maxとminを指定してやることで、起動時から常にスレッド数100でリクエストを待ち構えるようにする。

minの数を低くすれば起動時はそれの数になり、minを超えるようなリクエストが同時に発生すると最大maxまで増える。リクエストがなくなればそのうち減る

正しく指定できているかの確認

環境にあった起動方法でspringを起動する。自分の場合gradlewを使っているので以下で起動

./gradlew bootRun

JDKがあればjconsoleがコマンドライン上から使えるので、それでスレッド数の確認をする

jconsole

f:id:iku8:20210526123418p:plain

スレッド数100で起動したはずが120ほどのスレッドが起動されていた。どうやら20スレッドほど何かに使われているらしい。 ちなみにスレッド数を50に指定した場合は起動中のスレッド数が70となった。

画像左下には起動しているスレッドの詳細が表示されており、フィルタに「http-nio-8080-exec」と入力するとリクエストを受付処理するためのスレッドが絞り込まれる

f:id:iku8:20210526124019p:plain

正しく100スレッド起動されている

正常にリクエストがスレッドによって正しく処理されているかの検証

では最後に、1リクエストに対して、1スレッドが正しく割り当てられ処理されるかを確認する

まずは適当なコントローラを作る

@RequestMapping("bench")
@RestController
public class TestController {

    @GetMapping("mvc")
    public String webMvc() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(1000); // 1秒待つ
        return "this is mvc";
    }
}

1秒間ブロッキングされるようなコードにしたので、1リクエスト時に1スレッドは1秒間他のリクエストを受け付けられなくなる。

100スレッド起動しているので、100リクエスト同時にリクエストした場合は1秒間後に応答が帰ってきて、200リクエスト同時は2秒後に応答が帰ってくるはずである。

apachebenchを使ってリクエストを投げ検証してみる。

ab -n 100 -c 100 localhost:8080/bench/mvc

こんな感じで同時に100リクエストを送信可能

検証結果としては以下のようになった

※同時リクエスト200以降はspring側が受け付けられなくなったので、同時は100リクエストとして総リクエストを変えていくことにした。同時の場合も同じ結果が得られるはず(スレッド起動数100なので)

同時リクエスト数 コマンド 応答時間(s)
100 ab -n 100 -c 100 localhost:8080/bench/mvc 2.037
200 ab -n 200 -c 100 localhost:8080/bench/mvc 3.046
500 ab -n 500 -c 100 localhost:8080/bench/mvc 6.079
1000 ab -n 1000 -c 100 localhost:8080/bench/mvc 11.133

概ねリクエスト数に一致した応答時間が帰ってきた。1秒は何らかの処理でもっていかれるらしい。