2

私は3つのオプションを検討していますが、何か提案があれば、もっと提案を受け付けます.

問題: 睡眠をやめるように勧められ続けており、3 つの中から選択する背景がありません。

PHPスクリプトでスリープを使用するのは非常に悪いとよく言われますが、その理由を誰も強調していません。私はシステムをスケーラブルにするつもりです。つまり、この問題の解決策は 10 倍から 100 倍に使用できます。

オプション 1: スリープ

$timer = time() + (30);

while($done==0){
  $result = mysqli_query($mysqli, $query);
  $row_cnt = mysqli_num_rows($result);

  if ($row_cnt>0){
    $row = mysqli_fetch_array($result);
    print $row[0];
    $done=1;}

  else{
    $current = time();
    if( $timer>$current){sleep(1);}
    else{$done=1;}
  }

オプション 2:

私のサーバー以外の知識の上から睡眠を取り除くだけで、これはもっと悪いと思いますが、私は非常に間違っている可能性があると確信しています

else{
  $current = time();
  if(   $timer>$current){}
  else{$done=1;}
}

オプション 3: クライアントにループ内のページを要求させ、ファイルに単に情報を提示させることです。

$result = mysqli_query($mysqli,$query);
$row_cnt = mysqli_num_rows($result);

if ($row_cnt>0){
  $row = mysqli_fetch_array($result);
  print $row[0];

したがって、私の目標を考えると、どちらが最適ですか。

  • 信頼性 - 最も重要
  • クライアントが情報を取得する速度
  • スケーラビリティ - 重要度が最も低い (依然として重要)

ある方法が優れているという主張を本当に理解したい理由を教えてください

これが議論の余地があるとマークされた場合、それはすべての答えが有効であることを意味する必要があります:)そして私はそれを答えとして取ります:)

4

2 に答える 2

1

プログラマーがループで悪いと考える理由を突き刺しますsleep。これがあなたの質問の核心と思われます。

簡単な答え、はい、スリープを使用できます。

なぜあなたはそうしないのですか?

理想的には、データベースでデータが利用可能になったときに何らかの作業を行うことです。このため、データが利用可能になったときに通知を受け取ることができれば、最小限の作業しか完了していません。プログラミングでこれを実現する方法は複数あります。HTTP の世界での Webhook、ロック / セマフォ、コールバック、およびイベント / オブザーバーは、いくつかのパラダイムです。もう 1 つの理由として挙げられるのは、競合状態です。これについては、後ほど説明します。データベースは自動的に処理を行っているため、これはそれほど心配する必要はありません。

ただし、HTTP である理想的なステートレスな世界では、ロックすることはできず、イベントやコールバックを取得できない場合もあります。一部の AJAX プログラミングでは、固定間隔またはランダム間隔でのポーリングの使用が奨励されているのを見てきました。これは、サーバーに関する限り、基本的にスリープの一種です。

あなたのプログラムは無駄な作業をたくさんしているので、オプション2は最悪です。その無駄な作業はすべて、電力を消費し、他の場所に行く可能性のあるリソース (CPU) を浪費しています。コンピューターにログインしたり、他のプログラムを実行したり、Web サイトを提供したりすると、これらすべてが遅くなります。

于 2013-07-30T01:38:46.333 に答える
1

PHP がシングル スレッドであり、残りのスクリプトの実行を一時停止することを理解していれば、PHP のスリープを使用しても問題はありません。

これは間違いなく「正しいこと」ではありません。より多くのクライアントを接続し始めると、多くの apache PHP スレッドが発生し、すべてが同じイベントを待ってスリープ状態になります。リソースがすぐに不足してしまいます。あなたがやっていることは、本質的に長いポーリングです。寝ても寝なくても、それはまだ悪いです。

より良いアプローチの 1 つは、このシステムをよりイベントベースにすることです。イベントが発生すると、データがすべてのクライアントにプッシュされます。利用可能なテクノロジーに応じて、これは非常に柔軟になり、ネットワーク遅延のみが発生します. WebSockets のようなものがここに非常に適しています。

µC を使用していて websocket を簡単に実行できないため、サーバーへの永続的な TCP 接続を開き、データを送信するのが最善の方法です。

次善の策は、memcachedなどで結果をキャッシュすることにより、スクリプトを高速に実行することです。Memcached は基本的にメモリ内のキー値ストアです。clientId またはクライアントを一意に識別するものをキーとして使用します。プロセスは次のようになります。

結果データは外部ソースから更新され、データベースに追加されます。データが本質的にクライアントごとである場合、memcache 内のそのクライアントのキーを削除 (無効化) するため、結果をリクエストするときにデータベースに直接アクセスすることが強制されます。結果を記録するときに結果がクライアントごとでない場合は、現在接続されているすべてのクライアントを実行し、キャッシュを個別に無効にします。すべてが RAM にあるため、このプロセスは高速です。

クライアントが結果を要求すると、スクリプトは最初に clientID をキーとして使用して memcache を検索し、見つからない場合はデータベースにクエリを実行し、後で使用するために結果を memcache に入れます。

私は手元に良いmemcacheチュートリアルを持っていませんが、簡単な Google 検索でこれが見つかりました。

生の TCP ソケットの使用を再検討することもお勧めします。クライアントとサーバーの間でリアルタイム接続を確立でき、コード全体がよりシンプルになるため、本当に見逃しています。ホスティングで許可されていない場合は、より優れたホスティング プロバイダーを入手してください。安いものはたくさんありますが、月に 5 ドルまで払えない場合は、栄養が心配です。私が atm を持っているのは、RamNode と DigitalOcean の 2 つです。

それ以外は、状況をもう少し詳しく説明する必要があります。

于 2013-07-30T01:42:44.697 に答える