2011-03-15 12 views
31

私は、ユーザーがブラウザを使って互いにチャットできる(Facebookのチャットを考える)ウェブサイトを運営しています。ライブインタラクションを処理する最善の方法は何ですか? (今私は、オンラインのユーザーと新しい着信メッセージを更新する30秒ごとに行くの投票があり、別の調査では、新しいメッセージを取得するために、毎秒のチャットページに行く。)私が考えられてきたチャットアプリのスケーリング - 短いポーリングとロングポーリング(AJAX、PHP)

もの:

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

現在のところ、AJAX long pollingのスケーラビリティがわからないため、私は短いポーリングを使用しています。私は現在servintからVPSサーバーを実行しています(Apacheを実行しています)。長いポーリングや短いポーリングを使用する必要がありますか?私は絶対的な即時の応答時間(ちょうど "チャットアプリのために十分"良い)を必要としません。これを頻繁に行うポーリングは、数十万人のユーザーがサーバーを停止させることで行われますか?これをどのようにスケールするのですか、助けてください!

+1

私は、一般にApacheが多くの同時接続ではうまく処理できないことを知っています。また、このシナリオ用に構築された他のソリューション(nodejsなど)があるかもしれないことも認識しています。しかし今は、アプリケーション全体の書き換えを避けたいと思います。 –

+0

異なるプラットフォームで複数のソリューションを実装するにはどうすればよいですか?つまり、HTML5がサポートされている場合、ブラウザはHTML5を使用します。フラッシュがサポートされている場合はブラウザがフラッシュを使用し、上記のいずれもサポートされていない場合はブラウザがajaxを使用します。 – binaryLV

+0

この記事に興味があるかもしれませんhttp://urbanairship.com/blog/2010/09/29/linux-kernel-tuning-for-c500k/ –

答えて

41

いくつかの注意事項:毎秒は過剰です

  • ポーリング。アプリは、チェックの間に数秒間の遅延があっても非常に反応がよく感じられます。
  • dbのトラフィックと速度応答を保存するには、メモリ不足のメッセージを格納するためにインメモリキャッシュを使用することを検討してください。あなたは依然としてdbにメッセージを残すことができます。メモリ内のキャッシュは、新しいメッセージのクエリに単純に使用され、各ユーザーがx秒ごとにdbへのクエリを回避します。
  • サーバーへのポーリングを停止するためにx秒間何も操作しないと、ユーザーのチャットをタイムアウトさせます。これにより、ウィンドウを開いたまま誰かがトラフィックを生成し続けることはありません。シンプルな「まだありますか?チャットを続ける」を提供してください。タイムアウトしてタイムアウト前にユーザに警告するセッションのリンクを作成し、タイムアウトを延長することができます。
  • 私は、コメット/ロングポーリング/ソケットではなく、ポーリングで始めることをお勧めします。ポーリングは構築とサポートが簡単で、短期間でうまく機能します。多くのトラフィックが発生した場合は、ハードウェアとロードバランサを問題に投げかけてスケールすることができます。ウェブ全体はポーリングポーリングに基づいています。彗星/ロングポーリングなどの代替手段の複雑さが意味をなさない点がありますが、追加の開発時間/複雑さが正当化される前に、多くのトラフィックが必要です。
+0

あなたの最後のポイントは非常に参考になりました。私は、アプリケーションの最初のポーリング実装が将来どのように必要になるのかを判断しようとしていました。私はあなたのアドバイスを受け取り、簡単なポーリングを迅速に行い、長期的な解決策。 – simmer

22

これは、cometdとnodejの導入前に誰もが一度やったことです。

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

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

いくつかのテクニックを使用できます。

  • がある場合、クライアントはすぐにか更新することでこれに応じることができますどのように多くのメッセージなど、保留中の新しいメッセージである、チャットセッションに関するいくつかのコンテキストを持っているあなたの顧客に軽量のエンドポイントを提供します新しいメッセージはありません。このエンドポイントは、http要求を介して単純なjsonオブジェクトを提供できます。あなたはこのステータスメッセージが固定サイズになることを保証されており、ステータスの応答が変化しなければそれを崩壊させることができます。次のメッセージを見てください。

  • クライアントがサーバーから同じ応答を何度も受信すると、設定された時間だけポーリングを増やすことができます。現時点では1秒ごとです。これを行った場合、2,4,6,8,10秒ごとに増加します。サーバーからの応答が変わるとすぐに、減衰がリセットされます。

いくつかの最適化を検討してください。

  • APCのようなPHPオペコードキャッシュを使用してください。

  • すべての要求でタイムアウトを低く設定すると、サーバーをハングする要求はありません。

  • PHPコードを最適化して、それをすばやく速くします。

  • いくつかの負荷テストを実行して、制限値を確認してください。

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

  • アプリケーションの全体的な健全性と応答時間を通知するために、Apacheログを確認します。

スケーリングが必要になった場合は、新しいサーバーを追加し、ロードバランサを使用して要求を配信します。私は大きな成功を収めたVarnishとHAProxyを使用しました。それらを設定することも複雑ではありません。

+0

ダイナミックインクリメントは、私が考えなかった、本当に良い点です – JayIsTooCommon

1

私はあなたがhtml5が利用できない場合、まだフラッシュソケットに落ちるhtml5ウェブソケットを使用するライブラリを選ぶでしょう、クラックを通過するブラウザは分でなければなりません。

また、phpを放棄するか、Pythonまたはem-websocketを使用してrubyで書かれたスレッドソケットサーバーで補完する必要があります。

関連する問題