Действительно ли ReactPHP асинхронен?
Я делал некоторые тесты на ReactPHP, потому что это выглядит довольно потрясающе. Я протестировал его с помощью следующего реакции/сокета для простого сервера сокетов.
$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
после того, как все клиенты обработают (так ~ 2 секунды), но сервер покажет New client !
без ожидания.
Итак, здесь я не понимаю, ReactPHP - это асинхронный ввод-вывод, но PHP однопоточный, и если есть много обработки между входом и выходом, это блокирует всех клиентов.
Ответы
Ответ 1
ReactPHP - это асинхронный ввод-вывод, но PHP является однопоточным, и если между входом и выходом имеется много обработки, это блокирует всех клиентов.
Да.
ReactPHP очень вдохновлен node.js, который следует тому же принципу. Цель таких шаблонов, основанных на событиях, заключается не в использовании вашего сервера 16 CPU, а в том, чтобы полностью использовать ваш процессор, обрабатывая HTTP-запрос B, в то время как ваш контроллер для запроса A, который сделал запрос к базе данных, приостановлен до тех пор, пока не будет достигнут успех запроса базы данных 'вызывается событие.
Ваш тест идет точно против предположения, сделанного node.js и ReactPHP: "вычисление выполняется быстро, ввод-вывод медленный", поэтому, если мы делаем вычисления во время ввода-вывода (а не между вводами/выводами), тогда время CPU всегда будет доступно в большем количестве, чем необходимо.
С помощью node.js или ReactPHP, если вы хотите использовать свой серверный 16-процессорный сервер, вы просто запускаете 16-серверный процесс на 16-порте и устанавливаете перед ним балансировку нагрузки, такую как nginx.
Но имейте в виду, что ReactPHP все еще экспериментальна и не готова к производству.