17 мая 2019 г.
Всем привет! Сегодня я в Москве на конференции PHP Russia 2019. Представляю вашему вниманию краткий конспект докалада "Асинхронный PHP". Автор доклада - Антона Шабовта из компании Onliner.
Основной смысл асихронности - не блокировать основной поток выполнения. Соответственно, асинхронная опарация - это такая вот неблокирующая операция.
К блокирующим операциям относятся:
Для асинхронной работы с БД можно попробовать реализовать асинхронный SQL клиент. Автор приводит пример SQL клиента с мспользованием сокетов.
Одной из основных концепций асинхронности являются promise. Promise предполагает отложенную операцию, по которой пока нет результата, зато есть success(onResolve) и fail(onReject) callback. В дополнение к promise вводится класс Defered, который посути является фабрикой для promise.
Для обработки Promise используется EventLoop. Можно перевести как цикл событий. Event loop используется для обработки сообщений в асинхронной среде.
Клиент в цикле запрашивает у event loop результаты promise. Если promise уже отработал, клиент получает результат выполнения. В противном случае клиент продолжает запрашивать результат у event loop.
ReactPHP активно использует promises и соответственно, success/fail calback. При использовании ReactPHP довольно легко нарваться на callback/promises hell. Например, если нужно сделать promise, за ним еще promise и потом еще promise.
AMPHP использует cooroutines в связке с yield(генераторы). Генераторы в свою очередь реализуют Iterable интерфейс. В генератор соответственно можно отправлять данные и передавать ошибки. Cooroutine представляет собой сопрограмму.
В результате приходим к понятию кооперативной многозадачности. В обычной ситуацииоперации в запросе выполняются последовательно. При этом возникает ситуация, что блокирующие операции занимают относительно много времени и блокируют поток. В случае с асинхронным PHP можно "склеить" выполнение нескольких запросов и, грубо говоря, во время блокировки делать что-то еще. Подобный подход используется во многих продуктах, таких, как nginx, redis, memcached и nodejs.
Обработка запроса в php происходит примерно таким образом: Входные данные попадают на nginx в котором event loop реализован. Затем запрос распределяется между пулом php-fpm процессов. При этом их количество конечно и потенциально может стать узким местом. При этом каждый новый запрос обрабатывается с чистого листа, что добавляет свои особенности.
Преимущества:
Недостатки:
Следующим шагом к асинхроности будет написание своего асинхронного HTTP сервера на PHP. Основные задачи сервера:
В связи с асинхронностью возникает довольно много проблем разной степени серьезности:
Возможно, Event Loop в ядре PHP и появление функции await. Возможно, появление Generic и решение проблемы с указанием возвращаемого типа.
Скорость, производительность. Возможно увеличение производительности в несколько раз. В то же время,есть довольно много проблем. И, возможно, такие задачи стоит решать не на PHP.
Это был мой конспект, который я сделал в блиц режиме прямо на конференции. Тут могут быть ошибки или неточности. В будущем постараюсь их исправить. Доклад мне показался весьма интересным, правда использовать асинхронный PHP лично я наверное пока не готов. Хочу сказать спасибо докладчику Антону Шабовта и оргкомитету PHPRussia 2019. На этом пока все. Спасибо за внимание!