概要
SpringBootを利用してSQLServerに接続するアプリケーションにおいて、HikariPoolが以下のエラーを出してタイムアウトする事象について、原因と対処法についてまとめています。
# コネクションプール設定
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.
原因
・SpringBootで標準搭載されているデフォルトコネクションプールの最大サイズが「10」
・HikariCPのconnectionTimeoutがデフォルトで「30秒」
1回のトランザクション処理において時間のかかる処理があり、大量のリクエストが来て空いているコネクションが無く、30秒の待ち時間を経過してしまった場合に発生するというもの。
対処法
application.propatiesに下記の設定を追加しました。
# プールで維持するコネクション(使用中、アイドルの両方)の上限数
spring.datasource.hikari.maximum-pool-size=100
# アイドルなコネクションの数
spring.datasource.hikari.minimum-idle=50
# active、idle状況のコネクション数をログ出力
logging.level.com.zaxxer.hikari.pool.HikariPool=DEBUG
結果
コネクションプールが枯渇してシステムが落ちることがなくなりました!
コネクションプールの上限数を設定する上での適切な値の算出方法はまた調べてみたいところです。
最後に
私の担当していたシステムでは、稼働当初は特に問題は露呈しておりませんでした。
運用開始してしばらく後、データ数の増加に伴いクエリ1回あたりの応答時間も比例して増えたため今回の事象が発生してしまいました・・・
用語解説
HikariCP(ヒカリシーピー)
高速かつ軽量なJDBCコネクションプールのライブラリです。現時点では、Javaで実装されたコネクションプールのライブラリの中で最も高速という検証結果も出ており、RDBMSアクセス時の性能を要求されるような場合に有効なソリューションとなります。
いくつかのベンチマークにより、その高速性が証明されています。
コネクションプール
アプリケーション側(クライアント側)で予め一定数のDB接続を確保しておいて、それをアプリケーションで使い廻す仕組みです。DB接続を予め実行して貯めて(プールして)おき、その接続をアプリケーションで共有して接続時の高負荷を回避します。
Jmeter等を使用した負荷テストはしっかりやらないとです・・・