発生した問題
SpringBootアプリケーションからSQLServerに接続する際に、以下のようなHikariPoolのタイムアウトエラーが発生:
スタックトレース
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.
原因分析
- デフォルト設定の制限
- SpringBootのデフォルトの接続プールライブラリHikariCPのデフォルト設定値
- コネクションプール最大サイズ: 10
- コネクションタイムアウト: 30秒
- 問題が顕在化した経緯
- システム運用開始後、データ量の増加に伴いクエリの実行時間が長くなった
- 並行リクエスト数の増加により、利用可能なコネクションが枯渇
- コネクション取得待ち時間が30秒を超え、タイムアウトが発生
対策
コネクションプール設定の最適化
application.properties
に以下の設定を追加:
application.propaties
# コネクションプールの最大サイズ設定
spring.datasource.hikari.maximum-pool-size=100
# 最小アイドルコネクション数
spring.datasource.hikari.minimum-idle=50
# HikariPoolの状態監視設定
logging.level.com.zaxxer.hikari.pool.HikariPool=DEBUG
設定値の選定における考慮点
設定値はあくまで参考値です。
コネクションプールサイズの適切な値は、以下の要素を考慮して決定する必要があります:
- 想定される同時リクエスト数
- データベースサーバーのリソース制限
- 各トランザクションの実行時間
- アプリケーションサーバーのリソース
改善結果
- コネクション枯渇によるシステム停止が解消
- HikariPoolのDEBUGログにより、コネクション使用状況の可視化が可能に
用語
HikariCP
- JDBCコネクションプールの実装の一つ
- 特徴:
- 高速で軽量な実装
- 豊富な設定オプション
- SpringBoot 2.0以降のデフォルトコネクションプール
- ベンチマークで実証された高いパフォーマンス
コネクションプーリング
- データベース接続をプールとして事前に確保し再利用する仕組み
- メリット:
- データベース接続のオーバーヘッド削減
- リソースの効率的な利用
- アプリケーションのパフォーマンス向上
参考
- Springリファレンス
- HikariCP GitHub