2

中程度の負荷がかかると、特定のデータベースで次のエラーが発生することがあります。

「System.InvalidOperationException: タイムアウトが発生しました。プールから接続を取得する前にタイムアウト期間が経過しました。これは、プールされたすべての接続が使用中で、最大プール サイズに達したために発生した可能性があります。」


私はコードをくまなく調べて、確立したいくつかのケースを除いて、finally ブロックで接続を閉じていますが、非常にまれにしか呼び出されていません。次のリリースでこれらのコードを修正しますが、現在の本番環境の問題を解決するために、最大プール サイズを 300 に増やすことを提案しています。 100)。

また、複数の接続プールを不必要に作成しないように、特定の SQL Server インスタンスへのすべての接続文字列が同一であることを確認することもお勧めします。単一の SQL Server インスタンス内でデータベースを切り替える必要がある場合、実際の SQL クエリの前にUSE [Database]ステートメントを使用できることを願っています。

気を付けるべきアイデア、指針、提案、または落とし穴はありますか?

4

1 に答える 1

4

接続リークを排除する必要があります。プールの枯渇の原因がリークである場合、それを 300 に増やすことは、避けられないことを遅らせるだけです。10000 回の呼び出しで 1 つの接続をリークし (つまり、「ごくまれに」)、たとえば 5 秒の呼び出しで 110 の同時要求がある場合、8 分ごとに約 1 つの接続の割合でリークしていることになり、プールが枯渇します。 13時間。ただし、使用可能なプールのサイズが縮小するため、タイムアウトはかなり早く表示され始めます。

根本的な原因であるリークではなく、呼び出しの割合とプール サイズが実際に原因であるという確固たる証拠がある場合は、プール サイズを増やす必要があります。使用するプール サイズが何であれ、リクエストがリクエストの全期間にわたって 1:1 接続を必要とする場合は、プール サイズを超えないように HTTP 受け入れを調整/キューに入れる必要があります。そうでない場合でも、プールを使い果たすスパイクが発生する可能性があります。

また、プールが空になった場合にプールされていない接続を再試行する、より回復力のある接続ファクトリの使用を検討することもできます。もちろん、これは、プール サイズに一致するように最大 HTTP 受け入れカウントを調整すると、プールが使い果たされることはありません (リークしない限り、振り出しに戻らない限り) という以前のポイントと密接に関連しています。ただし、これはお勧めしません。アプリケーションのリソース割り当て領域よりも http.sys 領域でリクエストをキューに入れる方がはるかに優れていると思います (つまり、受け入れられる HTTP 呼び出しの最大数を調整します)。

最後になりましたが、各通話の時間を短縮します。呼び出しに平均 5 秒かかる場合、1 秒あたりわずか 22 のリクエストで同時に 110 の接続が表示されます。SQL のボトルネックを解消して呼び出しの時間を 1 秒に短縮すると、1 秒あたり 110 のリクエストを処理して同じリソース上限 (110 の同時リクエスト) を処理できるようになり、トラフィックが 5 倍増加します。通常、最大の原因はテーブル スキャンです。すべてのクエリが適切な SQL を使用しており、最適なデータ アクセス パスがあることを確認してください。David が言うように、SQL プロファイラはあなたの友達です。

SqlConnection.ChangeDatabaseを使用してデータベースを変更することもできます。

于 2009-07-31T01:56:00.043 に答える