サーバーは nginx
php-fpm
アーキテクチャを使用し、redis は接続に connect を使用します。各ネットワーク リクエストには個別の php-fpm
プロセスが必要です。ループ内に blPop/brPop
と sleep(5)
を含むループを書きました。ブラウザは 2 つのタブを開いて実行し、lpush
が 4 つのデータを list
にロードしました。常に最初に実行されていたタブが最初の 2 つのデータを読み取れることがわかりました。言い換えると、blPop/brPop
は、同じキーをリッスンするサーバー全体上の他のすべての blPop/brPop
をブロックします。
私がテストしたコードは次のとおりです:
最初に実行されるプロセスのスリープ期間中、後で実行されるプロセスがブロックされるのはなぜですか?
さらにテストを行い、ループを削除し、各プロセスを 1 回だけ実行し、各読み取り後に redis->close()
を使用したところ、2 つのプロセスの終了時間は依然として約 16 秒異なることがわかりました。
前回のテストでは、再度 2 つのサーバーに配置しましたが、今回は同じサーバー上の 2 つのプロセスではなく、2 つのサーバーの終了時間 (秒数) が異なることがわかりました。 2 つのサーバーに挿入した秒数。データ間の時間です。今回は遅延なし!
まず第一に、Redis はシングルスレッドであり、サーバーに送信されたリクエストはキューに入れられ、順番に実行されます。そのため、各ネットワークリクエストは個別のプロセスを持つべきだと言いましたが、これは間違っていると思います
blPop 命令はクライアントをブロックします。サーバー側ではありません。そうしないと、シングルスレッド Redis にとって致命的になります。
2 つのタブを開いた後、プッシュ データが存在しない前に 2 つのクライアントを開くのと同じです。ブロック状態で、ブロック時間は 20 秒に設定されます。
データをリストにプッシュすると、2 つのクライアントが同じキーに対して brpop 操作を実行し、最初に brpop コマンドを実行したクライアントが Pop 値を取得できます。つまり、最初のタブページは 5 秒スリープし、別のデータをポップしてから出力します。最初のクライアントがまだポップ行を実行している場合は、開始間隔であれば後続の値を出力する必要があると思います。 2 つのクライアント間の間隔が非常に短いので、おそらく終了します。2 つのクライアント間の開始時間の間隔を調整してテストしてください。ありがとうございます。
「すべてのネットワーク リクエストには個別のプロセスが必要です」という文は誤りであり、「すべてのネットワーク リクエストには個別の
php-fpm
プロセスが必要です」に変更されました。2 番目の質問は、おっしゃるとおり、2 番目のクライアントは後続の値を出力しますが、2 番目のクライアントが値を出力する時刻は最初のクライアントより平均 16 秒遅いのですが、その理由を知りたいです。短くなりますか? 2 番目のクライアントが最初のクライアントと同時にリッスンできないのはなぜですか?