4

今日、職場で次のような質問がありました。

多くの同時ユーザーが自分の Web サイトにアクセスしており、それぞれがユーザー セッションに独自のデータを保存しているとします。JVM で使用できるメモリの量が限られていることを考えると、同時アクティブ セッションがコンテナ JVM のメモリ不足になるポイントに到達すると、何が起こるか、または何が起こるはずなのでしょうか?

何が起こるべきかについてサーブレット仕様で何かを見つけようとしましたが、決定的なものは何もありません。開発者がセッションオブジェクトなどにアクセスできると言っているだけです。これは、プロバイダー固有である必要があると思います。

Tomcat を例にとると、Web サーバーはOutOfMemoryExceptions をスローし始めますか? それとも、セッションを別のキャッシュにページングするなど、これを処理する方法についてより賢いですか? それとも別の方法ですか?

4

2 に答える 2

4

サーブレットの仕様では、メモリに関する考慮事項については何も述べられていないため、何の助けにもなりません。

特にそうしないように構成されていない限り、Tomcat は HttpSession オブジェクト (実際にはそのコンテンツ) で利用可能なすべてのメモリを使い果たすことを許可し、最終的に JVM はOutOfMemoryErrors をスローし始め、サーバーをダウンさせる可能性があります (ただし、JVM は引き続き実行されます) 、多くのことが動作します...予期せず、残念なことに)。

単一のリクエストがローカル変数などで大量のメモリを使用し始めると、リクエストを処理するスレッドが影響を受けOutOfMemoryError、現在のリクエストの処理を停止します。(この場合、リクエスト処理スレッドはTomcatリクエスト処理スレッドプールによって実際にリサイクルされると思います)。その後すぐにガベージ コレクタが実行され、そのリクエストで使用されたメモリが再利用され、サーバーが安定します。

一方、大量のメモリを使い果たし、それらのオブジェクトをユーザーの に格納するとHttpSession、GC はメモリを解放できず、サーバーは継続的にOutOfMemoryErrors に悩まされます。Tomcat は指定されたスケジュールでセッションを期限切れにしますが (デフォルトでは非アクティブ状態が 30 分間続く)、セッション クレンジング スレッドはOutOfMemoryErrorduring 操作に遭遇する可能性があり、そのためにその義務を実行できず、状況全体が悪化します (事実上、HttpSessions が決して期限切れ)。

上記の不幸なシナリオを緩和する方法はいくつかあります。どちらが理にかなっているのかは、要件と環境次第です。

  1. ヒープ サイズを増やします。これは明らかにこれまでのところしか得られません。関連するオブジェクトで16GiB ヒープをいっぱいにする場合HttpSession、コモディティ ハードウェアの限界に達しており、単純に大きな箱を購入することはできません。

  2. セッションの有効期限を短縮します (デフォルトは 30 分です)。セッションが明示的に終了されていない場合 (たとえば、ログアウト関数によって)、HttpSessionオブジェクトとそのすべてのコンテンツは、有効期限が過ぎるまで残ります。放棄された多くのセッションに大量のデータがある場合、セッションの有効期限を短縮すると、息抜きの余地が生じる場合があります。

  3. ユーザーの に大量のデータを入れるのはやめましょうHttpSession。これは不愉快な提案のように思えるかもしれませんが (「それをやめてください」)、正直なところ有効な提案です: セッション自体にそんなに多くのものを保存する必要があるのでしょうか? ある種のデータ ストア (リレーショナル データベース、Cassandra のような非リレーショナル データベース、webcache など) を使用するのはどうですか? 多分データをディスク上のファイルに保存しますか?これらの提案は、データにすばやくアクセスする能力を確かに制限しますが、セッション内の非常に多くのものの重みでサーバーがクラッシュするよりは確実に優れたオプションです.

  4. Tomcat の を使用しますPersistentManager。これは、アクティブな (ただしアイドル状態の) セッションを外部ストレージにスワップできるセッション マネージャーです (ファイル ベースおよび JDBC ベースのストレージ メカニズムはデフォルトで利用可能です)。これにより、ユーザーのセッションに押し込んでいるすべてのデータを配置する別の場所を見つけるまでに、長い道のりを歩むことができます。

4 を除くすべてのサーブレット コンテナに適用できます。#4 は、JBoss が内部で Tomcat を使用しているため、JBoss ユーザーが利用できるはずです。他のコンテナについても、同様の機能が存在することがあります。

于 2012-08-14T20:11:47.683 に答える
0

通常、これはベンダーに依存します。ただし、コンテナーが独自の裁量でセッションをディスクにシリアル化できることがよくあります (セッション データをシリアル化できる場合)

コンテナーがこれを実行できる場合、必要に応じて非アクティブなセッションをプッシュし、必要に応じて再度復元することができます。これにより、メモリの使用効率が向上し、OutOfMemoryExceptions が延期されます。

于 2012-08-14T20:16:30.017 に答える