Привет, в августе мы проведем в Москве митап с докладчиками из других городов, встречей BeerPHP и трансляцией официальной части для всех, кто не сможет присоединиться.
Сегодня начинаем представлять докладчиков. Сергей Жук приедет на митап из Брянска — в его городе нет тусовки, а ему есть что рассказать об асинхронном PHP: он написал об этом книги, серию статей и не только. Ниже — расшифровка недавнего подкаста об этом, ссылки на прослушивание и просмотр выпуска, а также детали о самом митапе.
Пётр Мязин aka PQR: Сегодня со мной на связи один из главных знатоков ReactPHP. Сегрей, недавно я заходил на сайт reactphp.org и обнаружил тебя на главной странице. Ты достаточно много пишешь по теме, у тебя даже есть свой канал с видеороликами-инструкциями. Расскажи, как ты к этому пришел, что тебя зацепило в ReactPHP?
По сути, ты заново для себя открываешь язык, на котором уже пишешь много лет
Сергей aka seregazhuk: Два года назад, еще на предыдущей работе, нужно было написать скрипт, который постоянно бы обзванивал клиентов и работал очень быстро. Задачу надо было выполнить “еще вчера”, в команде были только PHP-разработчики, — времени на новый стек, сами понимаете, не было. Но так вышло, что все что-то слышали про ReactPHP. Он позиционировал себя как production-ready, все было очень легко: мы просто устанавливали company через composer, и можно было писать асинхронный код. В итоге написали решение на нем, запустили, все остались довольны.
Я понял, что инструмент-то у нас есть — но каких-то статей, практических примеров вроде «У нас есть такая проблема, мы ее решали вот так» ни на русском, ни на английском почти не было. В итоге я написал пару статей в своем блоге, получил положительный фидбек, и все — это как-то затянуло меня. Мы привыкли к модели Request- Response, но стоит погрузить в асинхронный код, и ты сразу спросишь: «А так можно было?».
Пётр: Давай еще раз проговорим, какую проблему для нас решает асинхронный код, и зачем нужен ReactPHP в частности?
Сергей: Почти в каждом приложении есть либо вызовы API, либо взаимодействие с файловой системой, либо запросы к базе. Когда мы ждем ответа от них, наш процессор простаивает — вместо того, чтобы заняться чем-то полезным. Можно не ждать ответа, а стартовать неблокирующие операции и двигаться дальше. Возникает вопрос: «Если мы везде для ввода-вывода поюзаем ReactPHP, то наши приложения станут в разы быстрее?»
К сожалению, нельзя просто так взять и переписать наши приложения на асинхронные
Сергей: Я бы задумался об использовании ReactPHP в тех случаях, где производительность критична, а ввод-вывод— это наш боттлнэк, который все блокирует. Более того, я бы порекомендовал не переносить все приложение на асинхронные рельсы, а именно переписать этот конкретный боттлнэк. Как правило, асинхронный кусочек гораздо легче вставить в традиционный блокирующий код, нежели пытаться переписать полностью все приложение.
Пётр: Ок, но почему бы нам тогда просто не запустить несколько PHP-процессов? Этот простаивает, зато соседний занимается делом.
Сергей: А как нам тогда координировать результаты? Допустим, нам надо получить данные из трех источников, мы делаем вызовы к трем API, потом компонуем результаты и отдаем пользователю. Если мы сделаем три отдельных потока, то возникнет проблема координации результата.
При асинхронном подходе мы просто запустили бы их, так скажем, параллельно, потом получили результат и обработали. При потоках придется как-то этот шарик координировать, то есть проблема с состоянием будет. Это, кажется, сложнее, чем асинхронный подход.
Пётр: Я понял. У меня в голове крутилась такая мысль: если мы хотим увеличить число пользователей. обрабатываемых в секунду, как бы весь стек приложения из Symfony запустить в асинхронном варианте и обработать большее количество коннекшенов?
Сергей: Я бы так не делал. Зачастую же приложение не тормозит прям целиком. Если встает вопрос производительности, скорее всего, внутри есть пара узких мест, которые тоже, скорее всего, выливаются в медленный ввод-вывод. И вот уже эти узкие места я бы переводил на ReactPHP.
Это выглядело бы как маленькая асинхронная программа внутри привычного нам блокирующего кода: например, мы вызвали три запроса параллельно, обработали их и отправили пользователю ответ, а общая длительность выполнения равнялась бы времени самого медленного запроса. Если бы в случае традиционного подхода, мы бы ждали первый запрос, второй и третий. Но приложение же не стало от этого асинхронным.
А если мы сравним это все с NodeJS и другими?
Пётр: А если мы сравним это все с NodeJS, допустим, или Go, там ведь действительно асинхронность через все приложение проходит. Все запросы к базе, к файловой системе — они все асинхронны внутри. Значит ли это, в принципе, если все написать в асинхронном виде, получается какой-то профит?
Сергей: Профит будет, если изначально проблема в вводе-выводе. Тогда да, мы ее решим. Наш код будет максимально работоспособен, сможет обработать максимальное количество задач вместо того, чтобы простаивать и ждать, пока вот этот вот вывод обработается. Но если изначально проблема не в вводе-выводе, то написав все асинхронно, мы вряд ли что-то выиграем, и можем получить сложный код, который тяжело будет и читать, и поддерживать.
Пётр: Возвращаемся к PHP. Значит, у нас есть ReactPHP, а из знаменитых аналогов Swoole, Amp и Ext-async. А расскажи в сравнении, в чем разница между этими проектами, и насколько ReactPHP хорош, быстр и есть ли у него какие-то недостатки по сравнению с тем же самым Swoole?
Сергей: Из всех троих, если честно, я щупал только Amp, и потому, что он, как и ReactPHP, поддерживается сразу из коробки. То есть мы ставим нужные компоненты через composer и готово. И здесь мне не очень нравится историям с расширениями. Потому что если мы остаемся наедине с PHP и асинхронностью, то, мне кажется, более разумно использовать язык и нативные вещи — а если мы используем дополнительные расширения, то здесь уже не особо асинхронный PHP, а асинхронные расширения для PHP.
Насколько ReactPHP реально production-ready?
Пётр: У них на сайте написано “long-term support”. То есть некая долговременная поддержка, без критических изменений API. Все так? Все достаточно качественно?
Сергей: Да. Сам проект ReactPHP уже достаточно взрослый. Он с двенадцатого года работает, получается ему же 7 лет. Он уже достаточное время production-ready. И да, более того, вот появился long-term support для основных компонентов на 2 года. То есть можно смело завязываться на эти компоненты, получать фиксы, обновления и не волноваться об обратной совместимости. Два года они обязуются поддерживать свои версии, ничего не сломается. Это, я считаю, прям реально круто, это большой такой шаг вперед. Насколько я помню, еще недавно Amp некоторые свои компоненты обсуждали, они не до конца определились с интерфейсом и со своим публичным API.
Пётр: С чего рекомендуешь начать изучение ReactPHP? Кроме официальной документации и твоих видеоуроков, конечно. Где все комьюнити, есть ли какие-то телеграмм-чаты или дискорд-чаты, форумы?
Сергей: К сожалению, не знаю таких вот таких прям комьюнити. Есть аккаунт в твиттере достаточно активный: там можно спрашивать, задавать вопросы и интересоваться. И майнтейнеры достаточно оперативно отвечают — можно в твиттере им лично написать. Я так делал, спрашивал у них какие-то вещи.
Пётр: Ну что, спасибо тебе за такой подробный рассказ о ReactPHP — и в связи с этим проанонсирую Panda Meetup, который пройдет 22 августа в Москве в офисе Skyeng. Ты там будешь выступать, верно?
Сергей: Да, все верно. Приходите, пообщаемся.
Пётр: Также там будет еще доклад про Domain Driven Design, что тоже классная интересная тема в контексте PHP, [и еще добавилась парочка других] и как мне сказали организаторы — будет некая афтепати.
Полезности:
- Полная аудио и ютуб-версия подкаста
- Ссылка на трансляцию митапа для тех, кто не сможет прийти
- Подробности об афтепати в телеграме BeerPHP Moscow
Автор: spasibo_kep