5

Tomcat のようなサーブレット エンジン/コンテナに支えられた Web アプリケーションがあるとします。ユーザーがログインします。そのユーザーのデータベース レコード (クラス User のインスタンスで表されるとしましょう) が読み込まれ、これをキー「currentUser」を持つセッション属性として保存し、一度設定して使用することができます。後続のリクエストを処理します。さらに、セッション属性にさらにオブジェクトを配置します。かなり基本的なもの。

ここで、いくつかの新しいコードをデプロイして Tomcat を再起動する必要がある場合...インスタンスがユーザーに格納されているクラスを変更しない限り、ユーザー セッションは再起動後もそのままです (ディスク/データベースから復元されます) 。セッション。しかし、これは大きな問題です。ユーザーが新しいコードのリリースでセッションを失ってほしくありません。

この問題を回避するために、セッション オブジェクトには、変更されないと想定されるクラスのインスタンスのみを格納できると思います (ログイン ユーザーの ID を User クラスのインスタンスではなく Integer として格納するなど)。その後、再起動時にセッション オブジェクトを逆シリアル化できないという問題に遭遇することはありませんでした。しかし、ID を使用してデータベースなどから実際のオブジェクトをロードする必要があるため、少し複雑になります (キャッシュを使用すると、パフォーマンスへの影響は実際には問題になりません)。

これは、この問題を回避するために通常行われていることですか?

4

3 に答える 3

3

シンプルなソリューション

あなたが提案したように、セッションで userId のみをロードし、ehcache などのキャッシュ サービスを使用してユーザー オブジェクトを取得します。ユーザー オブジェクトが存在しない場合は、最初に読み込まれますが、その後キャッシュされ、その後の要求はかなり高速になります。ユーザー クラスの変更が心配な場合は、キャッシュ メモリ ベースのみを作成して、サーバーの再起動時にリセットされるようにします。

プラットフォーム ソリューション

Terracotta (http://www.terracotta.org/) をご覧ください。セッションをプラットフォームにデプロイできる場合は、サーバーの再起動間でセッションを維持したり、古いフィールドを維持しながら実際のユーザー クラスを更新したりできます。起動して実行すると、かなりクールなもの。

ただし、Terracotta の統合は単純ではなく、初心者向けではないことに注意してください。ただし、利点は、すべての Web アプリケーションが一般に必要とするスケーラビリティと高可用性です。

于 2011-05-12T15:15:08.940 に答える
2

シリアライゼーションに関する限り、シリアライゼーション形式を変更しなければ問題ありません。そうしないと、恐ろしいInvalidClassExceptionが発生します。あなたがする必要があるのは次のとおりです。

  1. シリアル化するすべてのオブジェクトにa を設定しserialVersionUIDます。再起動の間にクラスのフィールドを大幅に変更しない限り、これで十分です。
  2. writeObject/メソッドをオーバーライドしてreadObject、シリアル化形式を正確に制御します。これを行うと、クラスの大幅な変更を回避することもできます。
  3. JSON/XML または翻訳を適切に処理するその他のストレージ形式を使用します。おそらくあなたの最善の策です。
于 2011-05-12T04:04:09.913 に答える
1

興味深い状況といい質問です。

通常、私がエンタープライズ環境で見たものから、セッションは通常、Web アプリケーションの新しいバージョンがデプロイされた後に強制終了されます。いずれにせよ新しいデプロイであるため、アプリケーション サーバーは通常、新しいアプリと新しいアプリの違いを認識していません。バージョン。サーバーがセッションを保持するのは良い考えではないと思います。これは、ユーザーがアクセス許可などを持っていない完全に異なるアプリケーションである可能性があるためです。これはセキュリティ上の問題である可能性があります。

ただし、セッションが永続化され、新しい展開でも復元できると仮定しましょう。あなたが説明する方法はほぼ正しいように聞こえますが、バージョンに基づいて変換 (またはデータベースから再度ロード) する必要がある古いオブジェクトがセッションにあるかどうかを確認するなど、もう少し洗練された方法で行うこともできます。Java では、アプリケーションの新しいバージョンがクラスを逆シリアル化できるように、クラスをバイナリ互換にするように努めます。それが writeObject/readObject の目的です。

もう 1 つのアイデアは、「セッション」を独自のデータ形式でデータベースに保存し、ユーザー認証や独自のアプリケーション セッション ID などの軽量データのみにセッションを持たせることです。ただし、Java アプリケーションでこれを見たことはありませんが、データを新しい形式に移行するために、展開時に必要なことを実行し、移行手順を実行することができます。auto-login/remember-me cookie と一緒に使用しても、ユーザーは何の違いも感じません。

于 2011-05-11T22:34:49.777 に答える