Чему я научился как синхронный PHP-разработчик, изучая асинхронный PHP
Я годами работал с Laravel. Я использовал синхронный PHP. Приходит запрос, запускается процесс, и уходит ответ. Мне никогда не требовался асинхронный подход.
Затем я прочитал о новом PHP 8.6 Polling API. Это изменило мой взгляд на то, как PHP обрабатывает задачи.
Вот разбор того, как работает асинхронность.
Проблема блокирующего ввода-вывода (I/O)
Когда вы вызываете API, ваш код ждет.
Пример: $response = Http::get('https://api.example.com');
Если этот API отвечает 300 мс, ваш PHP-процесс ничего не делает в течение этих 300 мс. Он находится в состоянии ожидания (sleep), удерживает память и занимает слот воркера. Если все ваши воркеры «спят», сервер перестает принимать новые запросы.
Асинхронное решение
Асинхронность позволяет выполнять другую работу в течение этих 300 мс. Вместо ожидания вы запускаете другие задачи.
Но как узнать, когда данные придут? Здесь в дело вступает ядро (kernel).
Эволюция опроса (Polling)
select()В PHP есть функцияstream_select()еще с версии PHP 4. Она спрашивает ядро: «Готовы ли какие-либо данные в этих сокетах?» Проблема заключается в «налоге на повторное сканирование» (rescan tax). Если у вас 10 000 соединений, вам приходится каждый раз отправлять весь список ядру. Это медленно и упирается в ограничения.epoll/kqueueЭто функция ядра, а не языка. Linux используетepoll. macOS используетkqueue. Вместо сканирования полного списка ядро поддерживает список готовых (ready-list). Оно сообщает вам только о тех конкретных сокетах, в которых есть данные. Это масштабируется до тысяч соединений без дополнительных затрат.Fibers (PHP 8.1) Fibers позволяют приостановить функцию в любом месте стека вызовов. Fiber не просыпается сам по себе. Это похоже на поставленное на паузу видео в YouTube. Кто-то должен вызвать
$fiber->resume(), чтобы запустить его снова.
Недостающее звено: PHP 8.6
Асинхронный ввод-вывод требует трех компонентов: • Пауза: Fibers (теперь в ядре PHP) • Решение: The Event Loop (обычный PHP-код) • Знание: Kernel Polling (пробел)
До сих пор в PHP не было нативного способа «узнать», какой сокет готов, без использования старых инструментов или расширений на C.
PHP 8.6 устраняет этот пробел. Он добавляет нативный Polling API в ядро. Он будет автоматически использовать epoll в Linux и kqueue на Mac.
Общая картина
Асинхронность — это не магия. Event loop — это просто PHP-код, который решает, когда вызвать resume() у Fiber.
Fibers дают возможность приостановки.
epoll дает «интеллект», позволяющий знать, когда нужно возобновить работу.
Если вы используете только синхронный PHP, вам не нужно менять свои приложения на Laravel прямо сейчас. Но понимание этой модели значительно облегчит освоение асинхронных библиотек, таких как ReactPHP или Amp.
Создавайте, а не просто потребляйте. Запустите код самостоятельно, чтобы увидеть, как он работает.
