web-dev-qa-db-ja.com

チャットアプリのスケーリング-短いポーリングと長いポーリング(AJAX、PHP)

私はユーザーがブラウザを介して互いにチャットできるウェブサイトを運営しています(Facebookチャットを考えてください)。ライブインタラクションを処理するための最良の方法は何ですか? (現在、オンラインユーザーと新しい受信メッセージを更新するために30秒ごとにポーリングを実行し、新しいメッセージを取得するためにチャットページで毎秒別のポーリングを実行しています。)

私が検討したこと:

  • HTML5 Web Sockets:すべてのブラウザー(Chromeのみ)で機能するわけではないため、これは使用しませんでした。
  • Flash Sockets:最終的にモバイルWebをサポートしたかったので、これを使用しませんでした。

現在、スケーラブルなAJAX長いポーリングがどの程度になるかわからないため、短いポーリングを使用しています。現在、servintからVPSサーバーを実行しています(Apacheを実行しています)。使用する必要があります。長いポーリングまたは短いポーリング?絶対に即時の応答時間は必要ありません(チャットアプリには「十分」です)。短いポーリングでは、数十万人のユーザーがサーバーを強制終了することがよくありますか?これをスケーリングするにはどうすればよいですか? 、 助けてください!

33
Andy Hin

いくつかの注意:

  • 毎秒のポーリングはやり過ぎです。アプリは、チェックの間に数秒の遅延があり、依然として非常に応答性が高いと感じます。
  • データベースのトラフィックを保存し、応答を高速化するには、メモリ内キャッシュを使用して未配信のメッセージを保存することを検討してください。それでもデータベースへのメッセージを永続化することができます。メモリ内キャッシュは、各ユーザーによるx秒ごとのデータベースへのクエリを回避するために新しいメッセージのクエリに使用されるだけです。
  • サーバーへのポーリングを停止するには、x秒間非アクティブになった後、ユーザーのチャットをタイムアウトします。これにより、ウィンドウを開いたままにしている人がトラフィックを生成し続けることがなくなります。簡単な「まだそこにいますか?チャットを続けてください」を提供します。タイムアウトするセッションのリンク。タイムアウトの前にユーザーに警告して、タイムアウトを延長できるようにします。
  • コメット/ロングポーリング/ソケットではなく、ポーリングから始めることをお勧めします。ポーリングは構築とサポートが簡単で、短期的には問題なく拡張できる可能性があります。トラフィックが多い場合は、問題に合わせてハードウェアとロードバランサーを投入できます。 Web全体はポーリングに基づいています-ポーリングは最も確実にスケーリングします。コメット/ロングポーリングなどの代替手段の複雑さが理にかなっている点がありますが、余分な開発時間/複雑さが正当化される前に、大量のトラフィックが必要です。
43
Cory House

これは、cometdとnodejsが導入される前に誰もがかつて行ったことです。

私が見ている問題はPHP Apacheでのリクエストは非常に高価です。チャットアプリケーションが毎秒メッセージをチェックすると、Apacheに応答するのに十分なリソースがない状況になります。リクエスト。改善が必要だと思う他の領域は、チャットアプリケーションのコンテキストを改善することです。

新しいメッセージを取得しないのに、なぜ毎秒更新されるのですか?メッセージがない場合はどうなりますか?

使用できるいくつかのテクニック。

  • チャットセッションに関するコンテキスト、保留中の新しいメッセージ、メッセージの数などを備えた軽量のエンドポイントをクライアントに提供します。クライアントは、新しいメッセージがない場合、すぐに更新するかどうかでこれに応答できます。このエンドポイントは、httpリクエストを介して単純なjsonオブジェクトを提供できます。このステータスメッセージは固定サイズであることが保証されており、ステータスの応答が変わらない場合は、それを減衰させることができます。次のメッセージを参照してください。

  • Javascriptポーリングの単純な減衰。クライアントがサーバーから同じ応答を連続して数回受信した場合、設定された時間だけポーリングをインクリメントできます。現時点では、毎秒と言っています。これを行うと、2、4、6、8、10秒ごとにインクリメントされます。サーバーからの応答が変わるとすぐに、減衰をリセットします。

考慮すべきいくつかの最適化。

  • PHP APCのようなオペコードキャッシュを使用します。

  • すべてのリクエストに低いタイムアウトを設定します。リクエストによってサーバーがハングすることはありません。

  • PHPコードを最適化し、無駄のない高速なものにします。

  • いくつかの負荷テストを実行して、制限が何であるかを確認します。

  • 多くの場合、パフォーマンスをベンチマークして、アプリケーションの速度が向上していることを確認します。

  • Apacheログをチェックして、アプリケーションの全体的な状態と応答時間の明らかな兆候を確認します。

スケーリングが必要になった場合は、新しいサーバーを追加し、ロードバランサーを使用してリクエストを分散します。私はVarnishとHAProxyを使用して大成功を収めましたが、セットアップも複雑ではありません。

23
Tass Skoudros

もし私がhtml5Webソケットを使用するライブラリを選択したとしても、html5が利用できない場合はフラッシュソケットにフォールバックするのであれば、クラックを通り抜けるブラウザはわずかなはずです。

また、phpを放棄するか、pythonまたはRuby withem-websocket)で記述されたスレッドソケットサーバーで補足する必要があります。

1
Joseph Le Brech