web-dev-qa-db-ja.com

Tomcat JDBC接続プール:testOnBorrow vs testWhileIdle

さまざまな理由で、プール内の接続が無効になる可能性があります:サーバー接続タイムアウト、ネットワークの問題...

私の理解では、Tomcat JDBC接続プールは、アプリケーションに提供する接続の有効性については保証しません。

プールから無効な接続が取得されるのを防ぐ(実際にはリスクを下げるだけ)ための解決策は、接続検証の構成のようです。接続の検証とは、データベースに対して非常に基本的なクエリを実行することです(例:SELECT 1; MySQLで)。

Tomcat JDBC接続プールには、接続をテストするためのいくつかのオプションがあります。私がおもしろいと思う2つは、testOnBorrowtestWhileIdleです。

最初に、testOnBorrowが最適なオプションであると考えていました。これは、接続をアプリケーションに提供する前に基本的に検証するためです(validationIntervalで定義される最大頻度)。

しかし、すぐに接続を使用する直前に接続をテストすると、アプリケーションの応答性に影響する可能性があることに気付きました。ですから、testWhileIdleを使用すると、接続が使用されていないときに接続をテストするため、より効率的になる可能性があります。

どのオプションを選択しても、無効な接続を取得することによるリスクは低下するだけのようですが、このリスクは依然として存在します。

だから、私は尋ねることになります:testOnBorrowまたはtestWhileIdleまたは両方の組み合わせを使用する必要がありますか?

ちなみに、validationIntervaltestOnReturnに適用されず、testOnConnectの目的が本当に得られないことに驚いています。

14
Antoine Mottier

これに対する100%の正解はありません。それはトレードオフとコンテキストの問題です。

  • ほとんどの場合、testOnBorrowは、使用のために接続がプールから返される前に、クライアントとdb-serverは話し合っています。
  • 「健全性チェック」が行われてからアプリケーションが接続を使用するまでの間に、サーバー接続の競合状態が停止することはまだ防止されません。
  • しかし、これをコーナーケースと見なすと、testOnBorrowはかなり良い保証を与えます。

  • これとのトレードオフは、接続を要求するたびに、データベースサーバーに対してクエリが(どんなに軽量であっても)行われることです。これはおそらく非常に高速ですが、コストはまだゼロではありません。

データベース接続の信頼性が非常に高いビジーなアプリケーションがある場合は、データから、「プールからのすべての接続要求の有効性チェック」のコストが接続の問題を検出する利点を上回ることがわかります。 。

  • 一方、アプリケーションが均一にビジーでない場合(ほとんどの実際のアプリケーションのように)、testOnBorrowオプションを使用することは非常に有益です。
  • それを最大限に活用して、使用する前に良好な接続を確保します。特に、失敗したDB操作から「簡単に回復できない」というコスト(再試行+手動介入+ワークフローの損失など)を考慮してください。

  • testOnIdleオプションがある場合を想像してください。これには、健全性チェックを行う前に、接続がアイドル状態になる(接続のアイドルタイムアウトに依存する)必要があります。

  • これはtestOnBorrowよりもパフォーマンスが向上していますが、独自の欠点があります。
    • 実際のapp-to-db-connectionsは、単にアイドルタイムアウトベースの破損ではなく、ファイアウォールルール、n/w輻輳、db-server-underingingメンテナンス/パッチングなどに基づいてドロップできます。
    • したがって、「接続検証」の種類がない場合に、データで観測された接続エラーの数のデータ測定に戻ります。
  • そして、このオプションで注意することの1つは、最大接続数でプールが最適に機能し、アプリのパフォーマンスが良好な場合と、何らかの理由でdb-serverが再起動などをした場合です。 (クライアントの観点から)すべてのライブ接続は、アイドルタイムアウトが開始されるまで、ほとんどエラーになります。したがって、アプリの接続が再び回復するか、アプリを再起動するまで、db-issue(ファイアファイトであったはずです)が少し複雑になります。

最後のデータポイントの1つは、一部のアプリケーションでは、クリティカルパスが「検証クエリ」時間ではないことです(できればミリ秒単位で)。アプリケーションには、対処すべき大きな問題があります。そしてもちろん、一部のアプリケーションでは、その時間が非常に重要です。

15
Raja Nadar

お知らせするために、これをテストしました。testOnBorrowプロパティとtestOnIdleプロパティの両方を使用することができます。

ただし、上記のように、アプリケーションが混雑しておらず、接続を保持する前に接続を検証できるため、testOnBorrowを一意に選択します。

コメントで指摘したように、testOnBorrowは検証クエリを必要としません。保持することを選択した場合は、単純な選択にすることができます。

jdbc.Hive.testOnBorrow=true
jdbc.Hive.validationQuery=SELECT 1

testWhileIdleを使用する場合は、次を使用できます。

jdbc.testWhileIdle=true
jdbc.minEvictableIdleTimeMillis=1800000
jdbc.timeBetweenEvictionRunsMillis=1800000`

DBCPの詳細: https://commons.Apache.org/proper/commons-dbcp/configuration.html

6
UltimaWeapon