web-dev-qa-db-ja.com

大きなデータをHTTPセッションに格納する(Javaアプリケーション)

http-session-or-database-approach を続けてこの質問をします。

私はこのアプローチに従うつもりです。

  1. ユーザーがカートに製品を追加するとき、カートモデルを作成し、カートにアイテムを追加して、DBに保存します。
  2. カートモデルをカートデータに変換し、HTTPセッションに保存します。
  3. 更新/編集は、DB内の基になるカートを更新し、セッションでデータスナップショットを更新します。
  4. ユーザーがカートページの表示をクリックすると、セッションからカートデータを選択して顧客に表示するだけです。

HTTPセッションに関して次のクエリがあります

  • 大量のデータ(ショッピングカート)をセッションに保存するのはどの程度良いですか
  • このアプローチはどの程度拡張可能ですか? (セッションに関して)
  • 私のアプリケーションは大量のメモリを消費し、要求しませんか?
  • 私のアプローチは大丈夫ですか、またはこれを設計するときに他の点を考慮する必要がありますか?

ただし、すべてのカートデータをセッションに保存する方法を制御できますが、カートデータに特定の情報をセッションに保存する必要がありますか?

4
Umesh Awasthi

J2EEセッションBeanオブジェクトではなく、HttpSessionオブジェクトを参照していると想定します。

サーバーが1つしかない場合、セッションは、ユーザーがリクエストを行うたびにアクセスできる一種のグローバルマップのようなものです。大きなオブジェクトでも小さなオブジェクトでも、どちらにしてもマップに配置できますが、それらをそこにどれだけ長く置いたかによっては、問題が発生する可能性があります。

ほとんどのアプリケーションサーバーは、有効期限が切れたセッションを削除するため、訪問者がしばらくしてサイトを離れると予想される場合は、セッションのメンテナンスを行う必要はなく、セッションを期限切れにするだけでアプリケーションサーバーはクリーンアップできます。お先にどうぞ。

ただし、多くのユーザーがサイトに長期間滞在し、これらの長期的なオブジェクトがセッションに残る可能性があり、これを処理するための十分なメモリがない可能性がある場合は、他の方法が必要です。 。

最も簡単な方法は、ある種のLRUキャッシュを使用することです。たとえば、 commons LRUMap を使用して、マップに最大サイズを設定し、不要になったアイテムを削除することができます。この方法では、ラージオブジェクト用のグローバルキャッシュを作成できます。ユーザーが多すぎる場合、キャッシュはデータを削除するだけです。キャッシュミスが多いとパフォーマンスが低下しますが、少なくともすべてが適切に機能します。

結局のところ、キャッシュを保存するための十分なRAMと、ミスを処理するための十分なデータベース帯域幅がない場合、どのようなトリックを使用してもアプリはクラッシュします。

HttpSessionを使用することの欠点:

  1. 複数のサーバーがある場合は、フェイルオーバーや負荷分散が複雑になります。
  2. セッションが長期間続く場合、一種のメモリリークになる可能性があり、データはそこでキャッシュされ、読み取られたりクリーンアップされたりしません。
  3. セッションはユーザーごとに共有されないため、汎用キャッシュとしては役立ちません。

キャッシュとしてのグローバルマップへの欠点:

  1. 自分でデータをクリーンアップするか、クリーンアップを実行するサードパーティのライブラリを使用する必要があります。
  2. 複数のサーバーがある場合、ユーザーはキャッシュを活用するために同じサーバーにとどまる必要があります。
  3. ただし、セッションとは異なり、ユーザーごとに共有できるデータがある場合、グローバルマップを使用すると簡単です。

一般的なパターンは、可能な限り最小限の情報をメモリに格納することであり、有用なデータのみを格納することです。このアプローチにより、アプリケーションがスケーラブルになります。

本当にスケーラブルなアプリケーションが必要な場合は、JBoss/Wildflyやその他のJava EE Con​​tainer。

Java EEにおける設計上の考慮事項は、EEはセッションBeanをできるだけ軽量に保つことです。

0
jacktrades