1

Web アプリケーションに Spring MVC 3 + Tiles を使用しています。動作が遅いので、お待ちくださいページが欲しいです。

私が知っているページを待ってくださいには、主に2つの方法があります。

  1. 長時間のリクエスト: ページの「お待ちください」ビットをレンダリングしてフラッシュしますが、アクションが終了するまでリクエストを完了しないでください。アクションが終了したら、JavaScript を使用して残りのレスポンスをストリーミングしてリダイレクトするか、ページを更新します。
  2. すぐに戻り、バックグラウンド スレッドで処理を開始します。クライアントはサーバーを (javascript またはページの更新によって) ポーリングし、バックグラウンド スレッドが終了するとリダイレクトします。

(1) はアクションをすべてシングル スレッドに保つため優れていますが、ページがアセンブルされてクライアントに返される前に各 JSP が完全にレンダリングを完了する必要があるため、Tiles では可能ではないようです。

そこで、(2) の実装を開始しました。@Async私の実装では、最初のリクエストは、Spring のアノテーションを使用して、バックグラウンド スレッドで操作を開始しますFuture<Result>。次に、数秒ごとに更新される「お待ちください」ページをユーザーに返します。

お待ちくださいページが更新されると、コントローラーはバックグラウンド スレッドの進行状況を確認する必要があります。これを行う最善の方法は何ですか?

  1. オブジェクトをセッションに直接配置Futureすると、ポーリング要求スレッドはそれを引き出して、スレッドの進行状況を確認できます。しかし、これは私のセッションがシリアライズ可能ではないということではないのでしょうか?
  2. セッションにある種のステータス フラグを設定し、終了時にバックグラウンド スレッドにセッションを更新させることができます。HttpSession オブジェクトを非要求スレッドに渡すと、デバッグが困難なエラーが発生することを非常に懸念しています。これは許されますか?どちらの方法でも、誰かがドキュメントを引用できますか? もちろん、セッションがメモリ内にある場合は問題なく動作しますが、セッションがデータベースに保存されている場合はどうなるでしょうか? 複数の Web サーバーがある場合はどうなりますか?
  3. セッション ID、または遅い操作のその他の側面に基づいて、データベースにある種のステータス フラグを設定できます。セッション データではなく、ドメイン データベースにセッション データがあるのは奇妙に思えますが、少なくともデータベースがスレッド セーフであることはわかっています。
  4. 私が逃した別のオプションはありますか?
4

1 に答える 1

1

問題はSpring MVCとは関係がないため、質問のSpring MVCの部分はかなり簡単です。この回答で可能な解決策を参照してください: https://stackoverflow.com/a/4427922/734687

コードからわかるように、作成者は tokenService を使用して未来を格納しています。実装は含まれていません。既にお気づきのように、フェイルオーバーが必要な場合に問題が発生します。

  • future をシリアライズして、2 番目のサーバー インスタンスにジャンプさせることはできません。スレッドは特定のインスタンス内で実行されるため、そこにとどまる必要があります。したがって、セッション ストレージはオプションではありません。
  • リンクの例のように、トークン サービスを使用できます。これは通常、オブジェクトを格納し、後でトークン (文字列識別子) を介して再度アクセスできる HashMap です。ただし、tokenService がシングルトンの場合、これは同じ Web アプリケーション内でのみ機能します。

解決策は未来を保存することではなく、代わりに作業の状態 (作業中、終了、結果で失敗) を保存することです。クエリ セッションと実行中のスレッドが異なるマシン上にある場合でも、状態にアクセスしてシリアル化できる必要があります。しかし、どうやってそれをしますか?これは、データベースまたはファイル システム (上記の例では、zip ファイルが利用可能かどうかを確認できます)、キー/値ストア、キャッシュ、または共通オブジェクト ストア (Terracota) に格納することで実装できます。 ...

実際、すべてのバッチ フレームワーク (Spring Batch など) はこのように動作します。ジョブの現在の状態をデータベースに保存します。ドメイン データと運用データを混在させることを懸念しています。しかし、ほとんどのアプリケーションはそうしています。大規模なアプリケーションでは、運用データとドメイン データの 2 つのデータベース インスタンスを使用する可能性があります。

そのため、作業の状態と結果をデータベースに保存することをお勧めします。
それが役立つことを願っています。

于 2012-03-13T17:17:39.047 に答える