0

オンラインで多くの解決策があるように見える質問を述べるのは嫌いですが、私たちのケースに対して有効なベストプラクティスの解決策を見つけることが実際にはないようで、選択の余地がないと感じました.

使用間隔が数時間から数か月まで異なる場合がある RESTful サーバー アプリケーションを構築しています。

サーバーは Jetty によってホストされています。ORM は使用していませんが、アプリケーションは 3 つの層 (WebService-、Business-、および Data Layer) に階層化されています。データ層は、Guice フレームワークを介して注入された1 つのクラスに存在します。JDBC (MySQL 接続) は、このクラスのコンストラクター内でインスタンス化されます。最初は、Guice がデフォルトで各リクエスト ( ref )で新しいインスタンスを作成することを理解する前に、接続が多すぎて多くの問題がありました。この問題を解決するために、またデータ層クラスはステートフルであるため、クラスを Singleton として注入しました。

接続がタイムアウトし、コンストラクターが 1 回しか呼び出されないため、新しい接続がインスタンス化されないため、REST アプリケーションがしばらく使用されていない場合に問題が発生する可能性があることを予測しました。

現在、複数の解決策がありますが、これを解決する最善の方法を見つけることができないようです。他のソリューションへの意見や提案は大歓迎です。

1. 構成された mysql タイムアウト間隔 を延長する これはベスト プラクティスではないと考えているため、実際には望んでいません。もちろん、リークしている接続オブジェクトがあってはなりませんが、リークがあると、利用可能な接続の空き領域がいっぱいになってしまいます。

2. 各メソッドの最初に新しい接続をインスタンス化し、最後に閉じる これは、私たちが理解している限り、多くのオーバーヘッドを引き起こすため、ベスト プラクティスではありません。

3. インジェクションを「リクエストごと」に戻し、各メソッドの最後にプールを閉じる 新しい接続をインスタンス化するだけでなく、それぞれで新しいオブジェクトをインスタンス化するため、これは #2 よりもさらに悪いことになります。リクエスト?

4. 各メソッドの開始時に接続のステータスを確認し、接続が閉じている場合は新しい接続をインスタンス化します。たとえば、mysql に ping ( example ) を実行し、例外がスローされた場合は新しい接続をインスタンス化します。これは機能しますが、いくらかのオーバーヘッドが発生します。この入力が実際にパフォーマンスに違いをもたらすかどうかについてのアイデアはありますか?

5. 接続がダウンしていることを示すメソッドでスローされた例外を明示的にキャッチし、そうであれば、新しい接続をインスタンス化します 。メソッドが、接続がすでに有効な場合に返されるものを確実に返すようにする方法を見つけます。

6. 接続プール を使用する アプリケーション サーバー (Glassfish など) を使用する場合を除き、接続プールについてはよく知りません。また、これで実際に問題が解決するかどうかも疑問です。そしてそうならば; 接続プールを提供するフレームワークに関する提案はありますか? ここでは、Jetty で PLUS を使用することを提案しています。

不明な点は質問してください。重要な情報を追加するのを忘れている可能性があります。これは私にとっては設計上の問題ですが、コードが役立つと思われる場合は喜んでコードを提供します。

前もって感謝します!

4

2 に答える 2

2

接続プールが最適です。
それらには多くの利点があります。

  1. 彼らはあなたのためにあなたの接続をチェックします - これはタイムアウトを扱います
  2. 接続数を制御します
  3. 完了したら、単に接続を閉じることができます-参照を保持する必要はありません

何らかのプールに接続を保持する必要があります。実際、弾丸を噛まなければ、最終的にはほぼ確実に自分で接続を作成することになります。古くならないように接続チェックを実装するまでに、毎回それらを再度開く必要がないようにある種の接続ホルダー、ある種の例外処理コード...あなたは私のドリフトを取得します.
私はdbcpboneCPを使用しましたが、どちらも非常に使いやすく、構成も簡単で、JDBC 接続の問題に対処するための何時間ものフラストレーションを解消してくれます。
私は Guice にあまり詳しくありませんが、オブジェクトに独自のファクトリ メソッドを提供する方法があると思います。そのため、それを使用してプールから接続を取得し、単純に呼び出すことができます。close()それらをプールに戻すのが終わったら。
Web サーバーを使用している場合は、常にinterceptororfilterを使用して接続を作業スレッドにバインドし、処理後にそれらを破棄できます。この場合、接続プロバイダーは現在のスレッドに関連付けられているものをヤンクするだけで済みます。

于 2013-02-17T22:26:46.447 に答える
1

代わりにインジェクトし、Provider<Connection>古いエントリを検出できる接続プールからプロバイダーに接続(編集:必要なときに)を提供してもらいます。

返されない接続は、プールから破棄する必要があります。

于 2013-02-17T22:22:14.667 に答える