ZFConf-2011. Фотоотчёт о конференции по Zend Framework.

// Май 17th, 2011 // PHP, Sphinx, Zend Framework, Веб-разработка

Ну вот я и вернулся из Питера, где в эти выходные проходила конференция PHP разработчиков ZFConf-2011. Для тех, кто ещё не догадался, конференция посвящена самому популярному каркасу веб-разработки «Zend Framework».

Конференция проходит уже в третий раз, предыдущая была в Киеве, а позапрошлая тоже в Питере. В этот раз организаторы попробовали сделать конференцию платной. С одной стороны это хорошо, т.к. ни в зале, ни в раздаточных материалах не было рекламы. С другой стороны, пришлось тратить деньги не только на билет (я приехал в Питер из Москвы), но и собственно на саму конференцию. Видимо именно поэтому народу было гораздо меньше, чем в прошлый раз.

Хотя с другой стороны, пришли только те, кому это было реально интересно. Во общем тут можно подискутировать. Сразу хочу сказать, что качество фоток не ахти, т.к. в наличии была только мыльница. Ждём качественных фоток от организаторов!) Все фотки — кликабельны.

Толстая модель. История разработки собственной ORM // Михаил Шамин

Первым был доклад «Толстая модель. История разработки собственной ORM» от Михаила Шамина из Геометрии. Всегда интересно узнать подробности о технологиях, которые реально используются командами. Особенно, если речь идёт о High-load проекте. Т.к. в Геометрии очень любят Redis а MySQL тем не менее используют, то у них возникла задача поиска сущностей в независимых хранилищах. Почитав Мартина Фаулера они совершенно верно решили разделить логику предметной области (бизнес-логику) и логику хранения данных. В кругах моих коллег мы называем классы первого типа просто «модели» а классы второго типа «базовые модели». Т.е. модель не знает, как она хранит данные. Наиболее подходящим паттерном оказался «Domain model». Подсмотрев интересные фишки в Doctrine2/Symfony ребята решили сделать описания мета-данных базовой модели (связи, свойства и их тип) в аннотациях к функциям/классам. И правильно сделали, я считаю! Хотя на after-party в пабе за кружечкой пива было высказано мнение, что если слишком углубиться в этом направлении, то процент всякого рода комментариев (а док-блоки это на минуточку тоже комментарии) будет очень большим, и найти строчку программного кода можно будет с большим трудом :-) Но я уверен, ребята такого не допустят. С производительностью, я думаю, у них всё нормально, т.к. парсинг аннотаций кэшируется, что есть гут.

Теперь поговорим о способе, которым достигается инкапсуляция механизма хранения. Если в Doctrine 1.х привычным подходом является наследование, то в Геометрии сделали это через обертывание (wrapping). Модель бизнес-логики оборачивается одной или несколькими моделями хранения (т.к. примесей в PHP нет, то приходится изворачиваться), которые перехватывают обращения к моделям бизнес-логики. Вообще этот подход очень похож на механизм хуков в Drupal, но со своей спецификой. Я так и не понял, возможно ли сделать так, чтобы объект хранился сразу в двух БД, ведь в этом случае методы примесей будут пересекаться, и тогда либо там должны быть цепочечные методы (на подобии Jquery), либо какой-то стек вызовов, или другой хитрый механизм. Для быстрого поиска они используют Sphinx, который индексирует данные и нескольких источников. Про Sphinx я ещё расскажу. Ну и конечно, они советуют избавляться от JOIN’ов. Это вообще модный тренд сегодня. А давайте как мы все JOINы выкинем, денормализуем нашу БД, перейдём на NOSQL, а потом… а потом будем иметь кучу головняков с реализацией функционала, который был на уровне БД, на уровне приложения. Спорный вопрос, в комментах готов выслушать мнение любой из сторон :-)

Итак, какой же профит от всего вышесказанного? Domain Driven Design! Мы работаем в терминах моделей предметной области, а не таблиц БД. Подобный подход очень хорошо реализован в DQL (Doctrine Query Language — разновидности Object Query Language ORM Doctrine). И да, с уверенностью скажу, что это большой плюс. Контроллер работает как вахтер, он вызывает методы модели, сервисов и т.д. не работая с уровнем хранения данных, сокращается размер функций-действий контроллеров и наступает мир во всем мире!) Хотя мне если честно больше нравится подход с использованием адаптеров и паттерна «Стратегия«. Резюмирую: программисты из Геометрии сделали правильный выбор, и, думаю, здорово оптимизировали процесс разработки.

Воюем за ресурсы: Повышение производительности Zend Framework приложения с помощью phpDaemon, Varnish и ESI // Алексей Качаев


Алексей детально рассмотрел проблему оптимизации скорости работы современных веб-приложений. Особенно мне запомнился слайд, где были формулы:

(nginx + apache + php + MySQL) * много

Вот это умножить на много меня повеселило. Действительно, в современных RIA или Ajax приложениях пользователь генерирует очень много запросов к серверу. Даже банальное автозаполнение (autocomplete) уже может напрячь вашу железку. Чего уж говорить про ExtJS сотоварищи. Дальше Алексей сделал профайлинг Zend Framework приложения и увидел, что 40-60% времени обработки запроса занимает … bootstrap! В моем ZF-приложении инициализация занимает 40%, так что да, очень большое количество ресурсов расходуется впустую. А потом говорят, что Zend Fremwork не подходит для Highload. Не верьте, надо просто правильно готовить. Вообще эта конференция прошла под знаком «ZF & Highload. Да это реально!». Итак после получения таких ошеломляющих данных можно сделать только один вывод — надо демонизировать PHP приложение. Один раз инициализировать его при загрузке, и потом в цикле обрабатывать поступающие запросы пользователей. С помощью чего это можно сделать? Для php есть phpDaemon, для javascript — Node.JS, для python — Tornado, для ruby — Eventmachine. Небольшой обзор я дал в этой статье. Но т.к. мы кодим на php возьмем за основу phpDaemon. Я около полугода назад сам занимался подобной штукой, но именно в этот момент автор phpDaemon решил вдруг поменять API…. Я решил подождать с реализацией, и взялся за другие дела.

Кроме phpDaemon Алексей использовал Varnish для кэширования, т.к. в nginx возможности формирования ключа сильно ограничены. Собственно там из возможностей — только конкатенация переменных запроса, а если надо что-то больше — компилируйте модуль nginx_perl_module, берите perl и вперед. Я и раньше знал про Varnish, но не знал, что его язык такой мощный и гибкий.

Общая схема выглядит так: Nginx + Varnish + ESI + phpDaemon (демонизированный ZF). Для определения блоков (фрагментов) используются ESI включения, их адреса обрабатывает Varnish, который если не нашел их в кэше отправляет запрос Nginx (на другой порт) и перекидывает их на демонизированный ZF. Почему не сразу на ZF? Для того, чтобы весь конфиг хранился в nginx. Так действительно удобнее, не фига плодить сущности. Для особо любопытствующих даю ссылку на исходники (спасибо Алексею). Ветка trunk — предлагаемый вариант, ветка classic — обычный (то, что было).

Я при решении такой задачи, как автозаполнение пошёл другим путём. Взял да и реализовал этот функционал отдельно от ZF, на обычном php, и сделал маленькую быструю утилитку, которая и выдавала на гора варианты поля. Естественно мне было любопытно, почему Алексей не пошел таким простым путём, а выбрал phpDаemon. На что он мне сказал, что запросы были не такими уж простыми, а затрагивали многие аспекты приложения и выносить и поддерживать их отдельно было бы слишком трудоёмко. В таком случае, я думаю, это оптимальный вариант. Георгий Туревич после этого спросил, а почему бы тогда всё приложение не вынести в демона, на что Алексей сказал, что они пробовали так сделать, но никаких преимуществ это не дало. Вообще с phpDaemon вызывает опасение две вещи.

  1. Он может потечь (утечки памяти), и хоть автор заявляет что всё ок, сомнения остаются.
  2. Надо грамотно переключать контекст. Приложение должно быть готово к демонизации.
  3. Иногда worker’ы phpDaemon’а могут подглючивать, и загружаться неравномерно.

Алексей коротко затронул непростой процесс установки демона. Приятно было видеть ссылку на свой блог :-)

Вообще приложение должно быть готово к демонизации. Требования к демонизации ZF приложения такие:

  1. Весь инициализационный код — в bootstrap. Соединения с БД, ресурсы и т.д. Всё туда. Bootstrap не должен зависеть от Request.
  2. Всё что касается запроса — прочь из bootstrap. Либо в плагины, либо в контроллеры. Определение языка не должно производиться в бутстрапе, т.к. в этом случае у нескольких подряд идущих запросов к одному воркеру будет один язык (язык первого запроса), а это неправильно.
  3. Никто кроме dispatch() не должен производить вывод. Всякие там json хелперы и т.д. могу испортить веьс процесс.
  4. Stdout в данном случае — это консоль демона, а не броузер.
  5. phpDaemon не должен получать запросы на статику, а то они могут его здорово подвесить.

Также есть ещё ряд перспективных направлений, таких как неблокирующий клиент MySQL и клиент для Memcached. Это может ещё больше ускорить работу приложения, ведь пока не пришел ответ от сервера, можно заняться другими запросами.
Резюме: маленькие задачи не затрагивающие множество аспектов приложения выносим в stand-alone php утилиты, задачи покрупнее — в демона, а само приложение (а количество запросов не него после первых двух пунктов здорово уменьшится) оставляем в виде mod_php/php5-fpm.

Behavior Driven Development в PHP и Zend Framework // Константин Кудряшов

Это был довольно интересный доклад.

Константин под вдохновением BDD системы Cucumber и языка Gerkin разработал две интересные системы: Behat и Milk, которые позволяют писать интеграционные тесты в таком виде:

Feature: Addition
  In order to avoid silly mistakes
  As a math idiot
  I want to be told the sum of two numbers 

  Scenario: Add two numbers
    Given I have entered 50 into the calculator
      And I have entered 70 into the calculator
     When I press add
     Then The result should be 120 on the screen

Самое интересное, автор продемонстрировал, что поддерживается и русский язык. Коллеги правда немного запутались (сказывается насыщенность конференции) с интеграционными и функциональными тестами.

Behat — это не юнит-тестирование, а именно интеграционное тестирование по user-story, а точнее feature. Самое интересное, что тесты для самого Behat сделаны на нём же :-) В начале доклада автор сделал короткий экскурс в юнит-тесты, TDD и BDD и описал суть проблемы, а именно налаживание контакта заказчика и менеджерами/разработчиками, т.к. очань часто они сами не понимают, чего хотят друг от друга.

Вот чтобы этого не было и нужно BDD. Моё мнение — идея хорошая, но работать в этом направлении надо ещё много.

Разделение труда: Организация многозадачной, распределенной системы в Zend Framework с помощью Job Queue // Александр Готгельф

Вот этого доклада я очень ждал. Александр работает в Magento и им встречаются тяжелые задачи. Например, пользователю надо отправить сообщение по электронной почте с помощью веб-приложения. Процесс этот не быстрый и может случиться так, что пользователь просто не дождется ответа. Решение: поставить такие процессы в очередь, а пользователям сообщать о готовности.

Автор исследовал разные средства для организации очередей. Zend Server предлагает удобные средства мониторинга и контроля, хорошо интегрируется с Zend Framework, но платен. А бесплатная community версия сильно ограничена. Следующим кандидатом стал Gearman, на ктором и было построено предлагаемое решение. Но оно тоже не лишено недостатков. Например, когда процесс забирает себе память, то после работы он не возвращает её операционной системе, и вполне может получиться утечка памяти таким образом. Зато, как плюс — клиенты и сервера можно писать на разных яязыках, и если у вас гетерогенная ИС, то Gearman можно использовать по аналогии со Thift, но для организации очередей.

Как может помочь среда разработки при написании приложения на Zend Framework? // Николай Матвеев

Ну этот доклад в большей степени был рекламный, однако хочу заметить, что phpStorm, о котором шла речь в нём — действительно качественная среда разработки. В мою бытность студентом, на курсе по Java программированию мы работали в системе IntelliJ Idea от разработчиков phpStorm. Я, да и многие Java программисты считают эту систему лучшей для Java-разрботки. phpStorm не отошел от традиций качества JetBrains.

Узнал для себя много нового. Например можно осуществлять навигацию по первым буквам классов, а т.к. в ZF ооочень длинные имена, это сильно помогает при разработке. Также докладчик осветил вопросы автоматизированного рефакторинга, навигации и т.д. JetBrains поддерживает OpenSource, на специальной страничке можно формить заявку на бесплатную версию IDE.

Что такое Sphinx, зачем он вообще нужен и как его использовать с PHP (от простого индекса до поискового кластера) // Владимир Федорков

Про Sphinx на конференции было сказано не мало. Недавно Sphinx презентовал общественности SphinxQL, который позволяет общатся с ним с помощью любого mysql клиента по SQL протоколу, а также SphinxSE, который позволяет делать это прямо из MySQL, и реализовывать, например, такие вещи, как JOIN из разных баз данных.

Как вам такая штука, первая часть данны — в MongoDB, вторая — в Redis, третья в MySQL, а четвертая вообще в XML, которая выгружается из 1С. Определяем всё это как источники данных для Sphinx, индексируем, ставим SphinxSE и делаем кросс-БД JOIN. Фантастик! Нет, теперь это реальность. Представляете, сколько времени мы сэкономим на сетевых задержках, которых теперь нет!

Кроме того появились такие фишки, как Real-Time индексы. Вернее появились они давно, но теперь можно обновлять в них данные обычным (ну почти) SQL-запросом, есть геолокационный поиск, когда надо найти ближайшие товары. Также реализована служба по коррекции ввода «misspeling correction service», которая автоматически исправвит опечатку и выдаст релевантные результаты по исправленному запросу, и поддержка UDF (User Defined Functions). О UDF в MySQL я писал совсем недавно, теперь такая возвожность доступна и для Sphinx.

Создание REST-API для сторонних разработчиков и мобильных устройств с авторизацией по протоколу OAuth 1.0 // Дмитрий Чижевский

Ещё один интересный доклад был посвещён разработки REST интерфейсов.



Основная проблема, по мнению автора, это недружелюбность REST к разработчикам клиентских приложений. Методов REST не хватает для реализации всех воздействий на приложение, но их и не должно хватать. Ведь основная суть REST в этом:

При подходе REST количество методов и сложность протокола строго ограничены, из-за чего количество отдельных ресурсов должно быть большим.

А значит надо быть готовым к большому количеству объектов. Автор добавил к REST API свои методы, которые назвал diffAPI и lazyAPI. Этот подход демонстрирует расширение протокола своими предметно-ориентированными методами, а CRUD операции остаются на ядре REST.

Второй проблемой было то, что REST в Zend Framework релаизован неправильно и нестандартно. Кстати поэтому у нас в компании своя реализация REST-контроллеров.

Дальше Дмитрий рассказывал об особенностях проведения аутентификации через Oauth в приложении. Грабель там не меньше, чем с OpenID. Но в версии OAuth 2.0 всё вроде бы получше.

Гибкая архитектура Zend Framework приложений с использованием Dependency Injection // Алексей Качаев

Закрывал конференцию Алексей Качаев, которого с уверенностью можно назвать фронт-лайнером ZendConf’а.

В докладе он подробно изложил, как можно осуществить постепенное внедрение принципа инверсии управления (Inversion of Control) и внедрение зависимостей (Dependency Injection) в Zend Framework приложение. Существуют два подхода: Service Locator и Dependency Injection.

На самом деле в ZF уже есть зачатки DI. Это HelperBroker и PluginBroker, которые бы в идеале надо объединить в один Dependency Injection Container.

Итак, для хранения ресурсов бутстрапа вместо ресурсов предлагается использовать DI контейнер, а именно Symfony DI контейнер. К сожалению, его нельзя просто так внести в состав ZF, т.к. у него хитрая лицензия, котоаря не позволяет вносить сторонние компоненты. Именно поэтому вопрос с DI в ZF до конца не решен. Далее, для получения сервиса ввести хелпер. По аннотациям к функции (вида Inject) можно судить, какие зависимости туда инжектируются.

Единственный минус такого приложения, оно зависит от контейнера зависимостей :-) Но тут, как говориться, ничего не поделаешь. Вообще я бы рекомендовал вам посмотреть исходники, там есть много всего интересного. В конце доклада Алексей рассказал об анти-паттернах внедрения IOC/DI, что тоже было очень интересно.

Конференция прошла успешно! Спасибо организаторам за мероприятие, провели конференцию на высоком уровне. После официальной части было приятно посидеть в баре за кружечкой пива. Ирландский KillKenny был фаворитом в этот вечер:-) Доклады были очень интересные и я не жалею, что съездил в Питер. Узнал некоторые новые приемы, познакомился с практическими сторонами внедрения веб-технологий, и самое главное понял для себя, что Zend Framework — рулит! Да, есть Ruby on Rails, есть другие технологии, фреймворки и каркасы. Сейчас мы видим, как лушие идеи перетекают от одной группы разработчиков к другой, и это дает возможность появится качественно новым технологиям!

Ну и напоследок видео флеш-моба, который мы застали в Питере во время нашей поездки.

 

Share

Спасибо!


Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:


3 Responses to “ZFConf-2011. Фотоотчёт о конференции по Zend Framework.”

  1. Ну и самый очевидный вопрос когда будет видео? =)

  2. Очень желаю, что и в этот год не удалось выбраться в Питер :( так хотелось побывать

Комментировать