Java/Kotlin
PR

SpringBootにkeepaliveのtimeout設定をする

saratogax
記事内に商品プロモーションを含む場合があります

AWS の環境で ELB(ALB)のアイドルタイムアウトの設定を変更する際、意識しておかなければいけなのがバックエンド側の KeepAlive やタイムアウト設定です。

For backend connections, we recommend that you enable the HTTP keep-alive option for your EC2 instances. You can enable HTTP keep-alive in the web server settings for your EC2 instances. If you enable HTTP keep-alive, the load balancer can reuse backend connections until the keep-alive timeout expires.

バックエンド接続では EC2 インスタンスで HTTP キープアライブオプションを有効にすることが推奨されます。EC2 インスタンスのウェブサーバー設定で HTTP キープアライブを有効にできます。HTTP キープアライブを有効にすると、ロードバランサーはキープアライブのタイムアウト期間が終了するまで、バックエンド接続を再利用できます。

Connection idle timeout

バックエンド側が Apache や Nginx のケースはこれまでに何度も経験してきましたが、SpringBoot(Tomcat)の場合はどうすればいいでしょうか。

今回はその辺を探っていきたいと思います。

デフォルトのKeepAliveTimeout

まず、何も特別な設定をしない場合の「KeepAlive Timeout」の値が何になっているのか確認します。

actuator を設定して env や configprops を確認しても、こちらが意図的に指定した内容しか確認できなかったので、起動後にプログラムから確認します。

下記の公式ドキュメントを参考に、「keepAliveTimeout」と「connectionTimeout」の設定値を確認します。

server.tomcat.keep-alive-timeout
server.tomcat.connection-timeout

っと何気なく書きましたが、サクッと Kotlin でサンプルを作ってみましょう。

これで確認する限り、デフォルトは 60 秒(60000ms)のようです。

override fun customize(factory: TomcatServletWebServerFactory) {
    factory.addConnectorCustomizers(TomcatConnectorCustomizer { connector ->
        val protocol = connector.getProtocolHandler() as AbstractHttp11Protocol<*>
        // protocol.keepAliveTimeout
        // protocol.connectionTimeout
    })
}

keepAliveTimeoutの設定

じつは Spring Boot 2.3 以降では、keepAliveTimeout を直接指定できる server.tomcat.keep-alive-timeout というプロパティが用意されています。

あわせて server.tomcat.connection-timeout も指定できます。120 秒(120000 ミリ秒)にするなら、application.yaml はこんな感じです。

server:
  tomcat:
    keep-alive-timeout: 120000
    connection-timeout: 120000

これで keepAliveTimeout も connectionTimeout も 120 秒になります。

なお、古い記事でよく見かける server.connection-timeout(プレフィックスなし)は Spring Boot 2.0 で非推奨になり、現在は上記の server.tomcat.connection-timeout に置き換わっています。

連続リクエスト数の上限にも注意(max-keep-alive-requests)

Tomcat は、1 つの keep-alive 接続で処理する HTTP リクエスト数にも上限があり、既定では 100 リクエストで接続を閉じます。

接続を長く使い回したい場合は、server.tomcat.max-keep-alive-requests を大きくするか、-1(無制限)にしておくと安定します。

server:
  tomcat:
    max-keep-alive-requests: -1

ALB のアイドルタイムアウトとの関係

AWS の定石として、バックエンド(Tomcat)側の keep-alive タイムアウトは、ALB のアイドルタイムアウトより長めに設定します。

逆にバックエンド側が先に接続を閉じてしまうと、ALB が再利用しようとした接続がすでに切れていて、502(Bad Gateway)が発生することがあるためです。

ABOUT ME
saratoga
saratoga
フリーランスエンジニア
仕事にも趣味にも IT を駆使するフリーランスエンジニア。技術的な TIPS や日々の生活の中で深堀りしてみたくなったことを備忘録として残していきます。
記事URLをコピーしました