2012-01-28 1 views
6

私は、最も効率的なやり方を知りません。誰かがより良いアルゴリズムを見つけるのを助けることができますか?頻繁にポーリングするとサーバーが過負荷になりますか?もしそうなら、ライブアップデートを実装する最良の方法は何ですか?

大丈夫ユーザーが投稿を投稿するとfacebookのような例があります。ページが更新されずに友人に更新され、ajaxリクエストでその情報がわかります。しかし、何人かが新しいことを投稿したことを、どうやって知ることができますか? 2秒ごとにタイマーを入れて、いくつかのテーブルのためにajaxリクエストを送信し、何人かのユーザーが何かを投稿したかどうかを確認するようなものでしょうか? 2秒ごとに操作を実行すると、重大なサーバーの問題が発生する可能性があるため、タイマを設定せずに行う方法はありますか?単にタイマーを設定するより良い方法があるかどうかを知りたいのですか?

ご協力いただきまして誠にありがとうございます。

+0

多分websockets? http://www.davesite.com/html5-code-tutorials/html5_interactive_intro_html_5/websockets/ –

+0

@niko ajaxベースのライブアップデートを使用する場合も同じ考えをしていましたが、他の解決策は見つかりませんでした。私はそこにサーバーとの接続を確立せずに解決策があるとは思わない。最悪のシナリオでは、2から4またはそれ以上の時間間隔を増やすことができます – motto

答えて

9

現在、FacebookとGoogleが採用しているのは、long pollingというテクニックです。

クライアントがサーバーにAJAX要求を行うのは簡単なシステムです。サーバーは要求を受け取り、要求に必要なデータがあるかどうかを確認します。そうでない場合、要求はオープンのままであるが、サーバによって遅延される。 2番目のサーバーにはデータがあり、要求が処理されてクライアントに返されます。

Facebookを開くと、Facebookに投稿されているリクエストが表示され、完了までに約55秒かかります。 Gmailや他のいくつかの種類のプッシュシステムを持っているようなウェブアプリケーションにも同じことが起こります。

ここでは、これらの要求が処理されるかもしれない方法の簡単な例を示します。

  1. クライアント:

    timestamp 0
  2. サーバーを持っている

    • 初期AJAX要求
      • サーバー上のデータのタイムスタンプを確認して、要求をtimestamp 0と比較してください。サーバー上のデータにtimestamp 234があるとします。
      • クライアントのスタンプがサーバーデータの現在のスタンプと異なるため、新しいデータが返されます。
    • クライアント:

      • クライアントがデータを取得し、すぐにtimestamp 234で新しいAJAX要求をポストします。
      • 次に、新しいデータを処理し、Webページを適切に更新します。
    • サーバー:

      • は、サーバー上のデータの現在のスタンプをtimestamp 234と要求を比較します。
      • スタンプの値は同じで、スリープ状態になります。
      • サーバーデータが更新され、スタンプ値がtimestamp 235になりました。
      • スリープリクエストが起動し、更新値とともに返されます。

あなたはライブアップデートのためのより近代的なメカニズムのよりin-depth説明を読むことができます。

+0

クライアント側では単純ですが、単一の要求を処理するコードを書く多くのWebフレームワークでは、効率的に行うのは簡単ではありません。 – 6502

+0

確かに同期があり、通常はある程度のキャッシュが必要ですが、間違いなく最も困難な同期問題を提案してください。それは楽しいだけではまだ簡単ではありません。明らかにFacebookやGoogleのように効率的なモデルを作成することは同じではありません。 –

+0

多くのWebフレームワークでは、リクエストを与えて返信する機能を書くだけで済むようになりました。ただ単に "スリープ"することは不可能です。他のフレームワークでは、保留中のリクエストごとに1つのスレッドが必要となる標準的なスリープ技術を使用することができ、これは必要なものよりはるかに効率が悪いです。サーバサイドで効率的にロングポーリングを処理するには(明らかに要求があったときにスレッドを使わないで)、明らかに可能で楽しいことです...しかし、 "シンプル"は私が使用する言葉ではありません。 – 6502

0

ちょうど私の2セントですが、私は以前2つのwebservicesを持って同様の問題を解決しました。基本的には、HaveNewData()と別のGetData()の行に沿ったメソッドを持つメソッドです(私の場合は、私が呼びたいwebservicesの数がありました)。

したがって、基本的にはHaveNewData()を呼び出してください(私はいずれの場合も2秒ごとにデザインが悪く、不要であると思います)、このメソッド(最小限のデータ)に対して単純な0または1を返します。 HaveNewData()が1を返したら、高価なWebサービス呼び出しを行います。あるいは、新しいデータが利用できないときにプライマリWebサービスでnull値を返すこともできます。私の経験では、少なくとも「かなり」合理的にスケーリングします。

0

ロングポーリングは優れた手法ですが、どのようなソリューションでも有効性はハードウェア設定を含む多くの変数に依存するため、絶対的な解決策はありません。

長いポーリングで接続を維持しています。は、多くのクライアントでパフォーマンスの問題を引き起こします。

あなたのソリューションを考慮に入れる必要があります: -

  1. それは(stockticker例えば)はほぼリアルタイムである必要はない
  2. どのくらいの頻度でAjaxのデータ/出力変更(新しいコメント対チャット)
  3. ajaxデータ/出力の変更を引き起こすイベントは、どのくらいの頻度でトリガされますか。これにより、キャッシュの生成方法が決まります。

あなたはajaxに関しては控えめでなければなりません。応答&を必要に応じて行う必要があります。 ajax実装の成功は、リクエストベースではなくイベントベースである、よく考えられたキャッシング・ソリューションがなければ、不完全なものになります。以下は

我々はプロジェクトに有用であることが分かっ手法の一つの簡易版である: -

  1. 行われるすべてのAjaxポーリング要求がで返されるデータのダイジェストであるoutput_hashが含まれていますサーバー。
  2. サーバは、好ましくはキャッシュに格納されているデータソースから、生成される出力の最近のハッシュに対して、このの出力_hashをチェックします。
  3. 異なる場合は、新しいコンテンツと新しいoutput_hashが表示されます。そうでなければ小さな応答/新しいコンテンツがないことを示すために変更されていない。

このソリューションでは、次のポーリング間隔の動的計算も行いました。間隔を動的に保つことで、サーバーは要求を制御できます。例えば、最初の1時間にほとんどのコメント/回答が起こったとすると、インターバル時間が1秒である点がないので、サーバは時間が​​増えるにつれて動的に2,3または5秒に増加させることができます間隔を2秒としてハードコーディングするよりも。同様に、古いポストに活動が慌ただしい場合、インターバル時間を短くすることができます。

アイドル状態のクライアントなどについても確認しました。

関連する問題