web-dev-qa-db-ja.com

ReactPHPは本当に非同期ですか?

私はReactPHPでいくつかのテストを行ってきました。次の react/socket コードを使用して、単純なソケットサーバーでテストしました。

$loop = React\EventLoop\Factory::create();

$socket = new React\Socket\Server($loop);
$socket->on('connection', function ($conn) {
    echo 'New client !';

    $conn->on('data', function ($data) use ($conn) {
        $conn->write("Wow, some data, such cool\n");
        $conn->close();
    });
});
$socket->listen(1337);

$loop->run();

この時点まで問題はありません。クライアントが接続され、クライアントが応答を受信すると、サーバーはNew client !を表示します。

しかし、dataイベントの処理を増やして、新しいテストを行いました。言葉を説明するために、完了するまでに数ミリ秒かかるforループを追加します。

$conn->on('data', function ($data) use ($conn) {
    $conn->write("Wow, some data, such cool\n");

    for ($i=0; $i<10000000; $i++); // here

    $conn->close();
});

この場合、10クライアントでは、クライアントはすべてのクライアントが処理した後、テキストWow, some data, such coolを表示します(so〜2 seconds)、しかしサーバー待機せずにNew client !と表示されます。

ここで私の理解の欠如、ReactPHPは非同期I/Oですが、PHPはsingle-threaded、入力と出力の間に多くの処理がある場合、すべてのクライアントがブロックされます。

31
Divi

ReactPHPは非同期I/Oですが、PHPはシングルスレッドです。入力と出力の間に多くの処理がある場合、すべてのクライアントをブロックします。

はい。

ReactPHPは、同じ原則に従っているnode.jsに非常に影響を受けています。このようなイベントベースのパターンの目標は、サーバーの16 CPUを活用することではなく、データベースへのリクエストを行ったリクエストAのコントローラーが「データベースリクエストの成功」まで一時停止している間に、HTTPリクエストBを処理することでプロセッサーを完全に活用することです'イベントが呼び出されます。

あなたのテストは、node.jsとReactPHPによって行われた仮定に正確に反しています:「計算は高速で、I/Oは遅い」ので、I/O中に計算を行うと(I/O間ではなく)、CPU時間は常に必要以上に大量に入手できるようにします。

Node.jsまたはReactPHPを使用して、サーバー16 CPUを使用する場合、16ポートで16サーバープロセスを起動し、nginxのようなロードバランサーをそれらの前に配置します。

ただし、ReactPHPはまだ実験段階であり、運用準備が整っていないことに注意してください。

50
jillro