2. Magento
About myself
Eugene Tulika
Magento Expert Consulting Group
Senior Developer / Team Lead
3. Magento
PHP in a Rocket Science
Agile
Time To Market
It’s a language to "solve the web
problem"
Enterprise Open Source
PHP Frontend / Java Backend
6. Magento
Asynchrony in PHP
Save User information
Send e-mail “User is created”
Save Shipping information
Save Order Information
Send e-mail “Order is created”
7. Magento
Asynchrony in PHP
UI Front Server Mail Service
Save User
information Send e-mail
“User is
Save Shipping created”
information
Save Order
Information
Send e-mail
“Order is
created”
19. Magento
Request/Response Tables
Request Id Request Data
1 {“Color”:”P!nk”}
Response ID Request ID Response Data
1 Null
2 1 {“Color”:”P!nk”,“Sa
ved”:”true”}
Меня зовут я работаю в Эксперт-консалтинг груп занимаюсь преимущественно кастом девелопмент последние полгода работал над интеграцией с x.commerceFabric. Это Платформа объединяюшая между собой различные системы. Работая над ней набил руку “мыслить асинхронно”. В процессе разработки пришлось на ходу изобретать множество решений как переложить понятия понятные в джава разработке в мир PHPСегодня мы поговорим о том месте в котором оказался PHP благодаря развитию индустрии
Сегодня, я хочу чтоб вы задумались о том, какое место занял PHP в современном мире. Я десятки раз слышал фразу «It’s not a rocket science” когда речь шла о PHP. От заказчиков; В интернете. PHP программисты порой сами так думают.По сути за этой фразой скрывается мысль, что ничего серьезного на PHP не напишешь. И все с тоской смотрят на Джаву – вот там есть все, распределенное программирование, паралельное программирование, потоки, очереди.Но на самом деле мир не стоит на месте. А PHP за это время очень уверенно занял нишу языка который в полном смысле слова “Agile”. На нем можно быстро написать, быстро потестировать, быстро задеплоить. Оверхед на обслуживание самого языка минимальный, что сокращает ключевую метрику Time To Market.Что такое PHP сегодня? - Enterprise Open Source. Звучит как оксюморон.часть ентерпрайз функционала под оберткой опен-сорс. Если вы пришли на мейджконф то вы о них прекрастно знаете. Большие компании желают сделать интернет магазин на гибкой стабильной плетформе, выбирают решение на PHP, и тут же его нужно интегрировать в текущую инфраструктуру. Таким образом это еще не энтерпрайз система сама по себе, но уже активный участник мира энтерпрайз. Sugar CRMТретее – мы все таки попали в сферу серьезных разработок. Почти 9 лет упирались руками и ногами, это не для PHP, в PHP это невозможно - web UI для серьезных систем
На этиъ графиках некоторые типичные схемы архитектуры Энтерпрайз Систем. Каждая из них в конечном итоге покахзывает инофрмацию пользователю. И каждая из них в конечном итоге предоставляет Web UI.Так мы постепенно очертили тот контекст, в котором дальше будут происходить события доклада. То с чем от проекта к проекту сталкивается Мадженто.Использлвание систем обмена сообщениями стало стандартом де-факто для крупных систем. Они облегчают интегрирование, оешают проблемы распределения нагрузки. Такой стандарт как JMS.Раз PHP вступает в эту сферу то оно должно учится работать с такими системамиИтак, почему мы говорим об асинхронности? Что это такое?
Что такое Асинхронность?асинхрнонно выполняющийся потокпотоки двигаются каждый со своей скоростью. Если бы какой-то поток начал дожидатся ответа, он поневоле стал бы синхронизироваться со скростью соседнего потока. Так же они могут двигаться каждый со своей скоростьюАсинхронность говорит о том, что один поток не дожидается другогоПо классу решаемых задач асинхронность относится к распределенным вычислениям.Легче говорить от противоположного. При синхронном выполнениии куски кода выполняются один за одним. При асинхронном следующий кусок может начать выполнятся раньше чем завершился предыдущий.Как это сделано?Во-первых потокамиВо-вторых распределенностью исполняющх узлов
- Давайте рассмотрим типичную форму шиппинга- на ней есть три секции- при нажатии на сабмит отправляет данные на сервер- сохраняет юзера- сохраняет шипмент- сохраняет информацию о покупке
- Первый же пример который найдете в интеренете кода будете искать асинхронность в PHP, будет рассылка e-mail ов. В целом логично – мыло рассылается практически в каждоим приложении на PHP, рассылка – операция не столько трудоемкая сколько длительная и вцелом отлично подходит для того чтоб вынести ее в отдельный процесс. - Это может быть даже отдельный скрипт на PHP, на который вы шлете курлом пост запрос, а он начинает рассылать письма.- Только не забудьте поставить авторизацию, например в хедерах, а то желаюших разослать письма на шару не мало
Почему это используют?- Ответ пользователю приходит быстрее- Легко балнсировать нагрузку, поскольку за работу с пользователями отвечают одни сервера, для обработки асинхронных запросов используются другие- Дает меньшая восприимчивость к сбоям, поскольку асинхронные запросы могут быть переадресованы на другой сервер- Уменьшает зависимость между компонентами системы Последние три пункта возможны только в распределенных системах имеющих несколько нод для обработки асинхронных запросов.
- Бывают ситуации, когда приложения, которые взаимодействуют посредствои обмена сообщеними должны дожидаться ответа на свои сообщения.Давайте представим следующий вариант развития событий. - Форма сабмиться и попадает на фронт сервер.Далее контроллер разбирает данные, первую часть посылает на сервер с юзерами вторую на сервер доставки Далее нам нужно собрать идентификаторы юзера и шипмента и послать на сервер заказов третюю на сервер пейментаТут для того чтоб послать третюю часть формы на сервер пеймента опрашивающее приложение должно дождаться Результата выполнении первых двух запросовудаленный вызов процедуры с помощью обмена сообщениями. Запрос – Сommand Message, ответ – Document Message
Message и Channel это паттерны из книжки про интеграционные паттерны.Они возникают в ситуации, когда пприложению нужно послать данные в асинхрнонно выполняющийся поток. Данные упаковываются в Message – к ним дописывается информация, которая позволит доставить сообщение по адресу – заголовок, сами данные – тело. Заголовок нужен для системы обмена сообщениями Канал представляет собой логический адрес в системе обмена сообщениями. В канале все сообщения однообразного формата. Сама система обмена сообщениями не диктует наличие каналов, они добавляются по ходу реализации системы. В то же время добавить канал после релиза проблематично, поскольку нет приложений которые бы использовали добавленный канал. Как приложиния интегрируются используя каналы и сообщения?- приложение 1 помещает сообщение в канал- приложение 2 слушает канал и обрабатывает сообщение- при надобности приложение 2 помещает ответ в канал
- Message Queue это уже не паттерн, а концеация. Она описывается целым набором паттернов – Message, Message Channelдля описания системы обмена сообщениями, и один из Competing Consumer, Polling Consumer, Event-Driven Consumerдля описания тех прцессов которые следят за поступлениями в очередьPoint-to-Point – один канал, меожество слушателей. Система сама заботится о том, чтоб каждое сообщение досталось только одному клиенту. Это может быть сделано либо с помощью диспетчера сообшений. Либо сообщение достается тому клиенту который первый подтвердит что он его получил.
Вернемся от книжных терминов к конкретной реализации на PHP в которой мне довелось поучаствовать.Задача ставилась таким образом, что некое ESB, для нас абстрактное фря, постило фиды с описанием продуктов, которые нужно было заимпортировать.По скольку серверов было три, то их работа была организована в виде очередиНа каждый фид с данными контроллер создавал месседж в очереди База данных общая для всех серверов Процесс запускается по крону, лезет в базу и забирает свою часть работы. Ноды по крону коннектились к очереди, метили свой месседж. Месседж содержит ссылку на файл с данными фида – например 100 продуктовТут решался вопрос поизводительности и организации нескольких серверова в распределенную систему
Похож на паттерн обзервер для распределенных систем каждый подписчик должен быть оповещен о конкретном событии но только один раз сообщение о событии не считается потребленным пока уведомление не получат все подписчики
Вторая ситуация – запрос с помощью обмена сообщениями Сценарий применяется для выпронения запросов, например к базе данных приложения на том конце провода. Ответом в этом случае будет текст, содержащий информацию из базы данных.Третяя ситуация Уведомления/подтверждения – Приложение посылает сообщение о событии, посредством которого осуществляется уведомление, и дожидается получения уведомленияДля решения этих вопросов используется Request/Reply паттерн
Обмен сообщениями предоставляет одностороннее взаимодействие участвующих Иногда взаимодействие должно быть двухсторонним Канал сообщений передает сообщения только в одном направлении Для решения такой ситуации обычно вводят второй канал, канал ответовКанал запросов может быть Point-to-Point или Publish/Subscribe. Канал ответов как правило всегда Point-to-Pointпоскольку нет смысла устраивать широковещательную рассылкуСинхронная блокировка Асинхронный обратный вызов
Подход эмулирующий поведение Джава программыЦентральнй действующий елемент – сокет-демонПриложение посылает запрос на демонДемон пересылает его в канал запросов и подписывается на канал ответов для получения сообщенийКак только получил сообщение – пишет его в сокет PHP приложения
Requestor создает сообщение Сообщение посылается в Message Channelто как ресивер получает месседж зависит от типа канала – это месседж кью или паблиш-сабскрайб ченнел. Либо он будет получать апдейты (Subscriber), либо сам опрашивать очередь и забирать месседжи (Request Polling pattern – потребитель может запросить из канала следующее сообщение когда готов это сделать. Синхронный получатель – блокирует свое выполнение на момент получения месседжа)Receiver – Event-driven consumer. Асинхронный получатель. Нет работающего потока до тех пор пока поток обратного вызова не доставит сообщение. Потребитель может бездействовать до тех пор пока его не вызовет система обмена сообщениями
Проблемы реализации: основная проблема – необходимость держать соединение юзера пока мы ждем ответ на запрос. мы сужаем возможности системы только до одного ответа на каждый запросCorrelation Id pattern Подход хорошо работает для синхронных запросов, таких как например удаленный вызов процедуры, которые нужно передать через систему обмена сообщениями. Но для запросов таких например как например загрузка данных из удаленной системы его лучше избегать. Основная проблема – таймаут. Если при синхронном соединении время отклика включается в понятие QoS, то в асинхронных системах время ожидаения это эмпирическая величина вычисляемая
Поскольку в PHPнет потоков, то для эмуляции их использовались процессы.- Но проблемы тут тоже есть. Основная из них – таймаут. Если при синхронном соединении время отклика включается в понятие QoS, то в асинхронных системах время ожидаения это эмпирическая величина вычисляемая
При переходе на кешированные данные UIдолжен поменятся Никогда не говорить юзеру что все сохранено пока не пришло подтверждение этому по возможности хранить информацию о свежести данных Можно придумать еще сотни способов сказать юзеру о том, что интерфейс не готов. Самое важное обеспечить возможность того, что он подготовится.