HTTP ポーリングが非常に遅いのはなぜですか?
私が持っているのはボタンです。ユーザーがボタンをクリックすると、MySQL データベース フィールドが更新され、値がユーザーに表示されます。私は 800 ミリ秒ごとにポーリングしていますが、非常に遅延/グリッチがあります。ボタンをクリックしても、登録されないことがあります。実際には、800 ミリ秒ごとよりもかなり頻繁にポーリングする必要があります。
これは、一度に Web サイトに 1 人のユーザーしかいない場合にも当てはまります。
HTTP ポーリングが非常に遅いのはなぜですか?
私が持っているのはボタンです。ユーザーがボタンをクリックすると、MySQL データベース フィールドが更新され、値がユーザーに表示されます。私は 800 ミリ秒ごとにポーリングしていますが、非常に遅延/グリッチがあります。ボタンをクリックしても、登録されないことがあります。実際には、800 ミリ秒ごとよりもかなり頻繁にポーリングする必要があります。
これは、一度に Web サイトに 1 人のユーザーしかいない場合にも当てはまります。
リアルタイムの情報が必要な場合は、(頻繁に) ポーリングを避ける必要があります。以下では、なぜこれが間違っているのかを説明しようと思います。車の後ろにいる子供が毎秒「私たちはまだそこにいますか」と叫びながら、あなたはいつも「私たちはまだそこにいません」と答えているのと比較することができます.
代わりに、ロングポーリング/HTTP ストリーミングまたは Websockets のようなものが必要です。これは、車の後部座席にいる子供が毎秒尋ねるのではなく、「私たちがそこにいることを知らせる」ように言っているのと比較できます。これは前の例よりもはるかに効率的であると想像できます。
正直に言うと、PHP がこの種のアプリケーションに適したツールであるとは (まだ) 思いません。利用可能ないくつかのオプションは次のとおりです。
ホステッド ソリューション:
Pusher は、WebSockets を介してスケーラブルなリアルタイム機能を Web およびモバイル アプリにすばやく、簡単かつ安全に追加するためのホストされた API です。
無料のサンドボックス プランには、1 日あたり最大 20 の接続と 100,000 メッセージが含まれます。準備ができたら、有料プランにアップグレードするだけです。
Beaconpush は、HTML5 WebSocket と Comet を使用してリアルタイム Web アプリを作成するためのプッシュ サービスです。
自分自身をホストする:
Socket.IO は、すべてのブラウザーとモバイル デバイスでリアルタイム アプリを実現し、さまざまなトランスポート メカニズムの違いをあいまいにすることを目指しています。
非常に大きくなると、「自分でホストする」ソリューションは安価になりますが、一方で、pusherapp のようなものを使用すると、簡単に開始でき (フレンドリーな API)、それほど高価ではありません。たとえば、pusherapp の「Bootstrap」は、1 か月あたり 19 ドルで 100 の同時接続と 1 日あたり 200,000 のメッセージを持つことができます (ただし、小さな beaconpush の方が安い場合は => 計算してください :))。補足として、このプランには SSL が含まれていないため、機密データには使用できません。専用マシン (VPS) を使用すると、(単純な Web サイトの場合) ほぼ同じ金額がかかり、ストリーミング ソリューションも自分で管理する必要があると思いますが、規模が大きくなると、これはおそらくより魅力的です。
ユーザーがそれをクリックするたびに、MySQL データベース フィールドが更新され、値がユーザーに表示されます。
ディスク I/O (標準モードの MySQL) をメモリと比較すると、非常に遅いです。プロセスを高速化するには、 redis (永続的なスナップショットもあります) や memcached (完全にメモリ内)などのメモリ内データベースを使用する必要があります。私自身、redis は非常に高速で、シンプルで、永続的なスナップショットを作成できるため、非常に気に入っています。http://redistogo.com/は、5MB のメモリを備えた無料プランを提供しており、おそらくニーズを満たします。そうでない場合は、月額 5 ドルのミニ プランでカバーされる可能性がありますが、さらに大きくなると、VPS の方が安くなり、私の意見では好ましいソリューションです。
最善の解決策 (特に大きくなっている場合) は、VPS を使用して自分で socket.io/redis をホストすることです (費用がかかります)。本当に小さい場合は redistogo を使用し、そうでない場合は自分でホストします。また、beaconpush/pusherapp のようなものも使い始めます。これは単純であるためです (すぐに始められます)。socket.io のホスティング (大きくなったときに自分のマシンで試してみることをお勧めします) は非常に簡単ですが、私の意見では beaconpush/pusherapp よりも難しいと思います。
ラグ/グリッチ? クライアント側の問題のようです。ボタンのこともそうです。最初に JavaScript を順番に取得します。
ポーリングに関しては、0.8 は少しタイム クリティカルに聞こえます。ほとんどの国についてはわかりませんが、ここ第三世界では、単純なネットワーク パケットが数秒間遅延することがあります。(接続の切断、パケット損失、光の速度は言うまでもありません。) あなたのアプリケーションは、これらすべてに対処する準備ができていますか?
別のアプローチについては、割り込み駆動型の方がはるかに優れているという点で@Vernに同意します。HTTP 用語では、サーバーが送信する実際のデータを取得するまで応答を受信しない、長期にわたる HTTP 要求に変換され、遅延と帯域幅が最小限に抑えられます。(AFAIK)これはAJAXよりも古い手法ですが、最近名前が付けられました。「COMET」を検索すると、クライアント側とサーバー側の両方のライブラリが表示されます。
開始するには、Mozilla Firefox のFirebugのようなツールを使用して、サーバーに送信されるリクエストを監視し、ボトルネックを探すことをお勧めします。
Firebug はリクエストの各部分を分解するので、サーバーとの通信に問題があるのか、単に応答に時間がかかっているのかを確認できます。
@Vernの答えに加えて、可能であればサーバーにデータを事前にキャッシュさせ、すべてのクライアントが同じキャッシュからプルし、毎回同じデータに到達するために個別のMySQL呼び出しを必要としないとも言います。アップデート。次に、実際の DB データが変更されるたびに、PHP にキャッシュを更新させるだけです。
キャッシュとは、php がサーバー側のファイルに書き込むことを意味し、クライアントはその 1 つのファイルの内容を見て最新の情報を確認します。キャッシュにはもっと良い方法があるかもしれませんが、これまで個人的にこれを行ったことがないので、これが私の頭に浮かんだ最初の解決策です。
あなたが経験している遅延を引き起こす可能性のある多くのことがあります. サーバーは要求を十分に高速に処理できるかもしれませんが、クライアントとサーバー間の接続が遅い場合は、明らかな遅延が見られます。
最初にサーバーに ping を実行して、応答時間を確認してください。
次に、ポーリングではなく、割り込み駆動型のアプローチを検討することをお勧めします。これは、サーバーが応答した場合にのみ、次のリクエストを送信することを意味します。これは理にかなっており、サーバーが処理できなくなるまで、多くのクライアントがサーバーに要求を殺到することはありません。これは特に当てはまり、リクエストの RTT (Round-Trip-Time) がかなり長くなります。
それが役に立てば幸い。乾杯!