Опыт использования Liferay Portal в eСommerce

06ea5b7388304b5bb31fe7bf9e0ba94f.jpg

Многие из нас уже не раз писали разного рода магазины. Но большие e-commerce проекты в быстро растущей и развивающейся компании разрабатывать приходится нечасто. К таким решениям предъявляются дополнительные требования, такие как конфигурируемость, адаптивность к изменениям, возможности встраивания в другие системы и прочее. Для написания такого решения компания Netcracker использовала Liferay Portal фреймворк. В итоге получили достаточно преимуществ, но и без проблем не обошлось.

Задача


Компания Netcracker, в которой я работаю, занимается разработкой комплексных программных решений для глобальных телеоператоров и операторов связи. Бизнес таких компаний крайне зависит от развития технологий, которые, как вы знаете, очень часто меняются, что сильно сказывается на подходах к решению, казалось бы, стандартных задач в индустрии.
Если попытаться кратко сформулировать задачу, она будет звучать так: необходимо создать корпоративный сайт (далее по тексту — Сайт) одного из крупнейших зарубежных национальных телекоммуникационных операторов связи, покрывающий около 10 млн активных абонентов.
Сайт должен предоставлять возможность просмотра каталога предоставляемых сервисов, информацию о сервисах и их доступности в разных регионах с возможностью тут же приобрести любой из них, а также позволять конфигурировать их в соответствии с описанием. Кроме того, одной из важнейших функций сайта является настроенный личный кабинет пользователя, через который можно управлять приобретенными сервисами, изменять их конфигурацию и без обращения в call-центр делать все, что душе угодно. Также должна быть реализована возможность, позволяющая в будущем легко расширять и модифицировать интерфейс сайта, не внедряясь в детали интеграций, методы получения данных и кодирования.
Все данные о сервисах, их ценах, операциях покупки и изменениях предоставляются модулями продуктовой линейки Netcracker, построенными на основе платформы — Netcracker Framework. Эти данные можно легко получить через REST API, предоставляемый этими модулями.
Остается только получить данные, закешировать все возможное, отобразить на сайте, красиво оформить и запустить сайт02e50d852cb44ca8924a03db4808190c.png
Но так как у нас есть много дополнительных требований, приходится думать и над нефункциональными сценариями использования. Например, заказчику необходимо:

  1. Регулярно проводить промо-акции, делать скидки, вводить новые сервисы.
  2. Периодически менять дизайн страниц, элементов пользовательского интерфейса. Например, срочно оформить сайт к Новому году и к Black Friday.
  3. Уметь отображать на сайте контент, который предоставляют подрядчики.
  4. Интегрировать корзину в каждую страницу общего портала оператора.
  5. Иметь возможность без единой строчки кода добавлять новые сервисы существующих типов, а также новые типы сервисов.


Выбор технологии


В качестве платформы для создания решения был выбран Liferay Portal — это портальное решение, поддерживающее спецификацию JSR-168 и JSR-286 (портлетная спецификация), содержащее в себе много разнообразных модулей, которые из коробки позволяют строить расширяемые, управляемые и конфигурируемые приложения. Кроме всего прочего, Liferay Portal (далее Liferay) включает в себя полноценную CMS, интеграцию с социальными сетями, форумы, чаты и прочее. Liferay позволяет строить страницы из кубиков, называемых портлетами, создавать которые могут как сами разработчики решения, так и сторонние компании, используя спецификацию JSR-286.
Liferay является одним из самых популярных бесплатных решений для построения корпоративных порталов и порталов общего доступа. Например, известный многим Java-разработчикам JUG.ru построен именно на нем.
Благодаря архитектуре, предлагаемой Liferay, конфигурация без написания кода будет сводиться к накидыванию на страницы нужных блоков (портлетов), заданию им параметров и прав доступа/ отображения.
Кроме того, Liferay предлагает очень хороший набор модулей Out-of-The-Box типа CMS, интеграцию с социальными сетями, оптимизацию для поисковых машин, интеграцию с системами Single Sign On и сторонними аналитическими сервисами.

Особенности реализации


Обдумывая задачи 1 и 2 (описанные выше), мы поняли, что необходимо дать возможность самому заказчику напрямую влиять на отображение каждого портлета и всего сайта в целом. Кроме того, для разгрузки сервера и улучшения восприятия сайта, хотелось сделать многие операции асинхронными и динамичными. С этой целью в проекте начали использовать темплейтный движок Google Closure Templates.
Этот движок позволяет с легкостью использовать один раз написанный шаблон как на сервере, так и на клиенте. Кроме того, очень качественно продумана локализация, интернационализация, разбивка на подшаблоны и многое другое. Больше всего привлекали лаконичность, уход от логики в шаблонах, избавление от многих типов стандартных ошибок (типа эскейпинга и пр.). Также нравилось, что шаблоны являются компилируемыми сущностями, что позволяет серьезно увеличить производительность как на сервере, так и на клиенте.
Решили сделать так, чтобы заказчик всегда мог подправить шаблон для любого портлета (кубика страницы) на свое усмотрение. Общий же вид портала можно править в шаблоне темы.
Для удобства разработки был написан микрофреймворк, позволяющий писать каждый портлет с использованием Spring MVC и Google Closure Templates в качестве View, а также небольшой JavaScript класс, инкапсулирующий в себе: всю логику асинхронного доступа к портлетам, отложенную их отрисовку по шаблону на клиенте, получение данных, доступа к DOM контейнеру портлета и прочее. Также была добавлена возможность связать JS класс, отвечающий за динамику в данном портлете, и сам портлет.
Благодаря этому разработчик не задумывается о том, что шаблоны должны компилироваться и пишет привычный для него код на Spring, HTML, JavaScript.

Результат


Liferay Portal оказался достаточно стабильным порталом. Порадовала его изначальная направленность на горизонтальное масштабирование, наличие кучи Java API«s и точек расширения, позволяющих поменять чуть ли не все что угодно. Также очень порадовало большое количество конфигурационных свойств, изменение которых позволяло быстро переходить от высоко оптимизированного кода страницы и статики к его девелоперской конфигурации, в которой намного проще отлаживаться. Вообще, создалось впечатление, что платформа создана программистами для программистов!
Google Closure Templates оправдали абсолютно все ожидания. Теперь это мой фаворит среди шаблонизаторов!
Возможность строить страницы для сайта из кубиков, которые напрямую друг с другом не связаны, а общаются только по шине событий, действительно прекрасна. Код получается хорошо структурированным, разбитым на логические части. При этом получаешь дополнительные преимущества: возможность использовать один и тот же портлет с разными внешними видами на разных страницах без единой строчки кода, простоту изменения внешнего вида страницы за счет легкого (drag&drop) перемещения блоков по странице, независимость работы всей страницы от работоспособности конкретного портлета.

Проблемы и решения


Главной проблемой, с которой мы столкнулись и которую до сих пор не решили красиво, стала конфигурация Liferay. Дело в том, что она хранит в себе практически все, что позволяет сайт назвать сайтом: содержимое CMS, настройки каждого портлета, привязанные к странице, темы страниц, лэйауты и многое другое. Поэтому есть серьезная необходимость как-то уметь переносить эту конфигурацию с одного места на другое. Кроме того, необходимо эту конфигурацию хранить и версионировать. Ну и вдобавок при разработке очень бы хотелось иметь возможность мержить изменения конфигурации. Пока мы видим два пути переноса конфигурации в Liferay:

  • Первый путь — Staging environment.Суть его в том, что ставятся два инстанса Liferay: один — это мастер изменений, второй — продакшн. На первом вносишь все изменения, убеждаешься, что они работают, и после этого нажимаешь кнопку [Применить]. После этого все изменения чудным образом перемещаются на продакшн сервер. Но, к сожалению, этот подход не удовлетворяет многим требованиям, описанным выше.
  • Второй путь — Export/Import — казалось бы, идеальная и правильная штука, но и тут не обошлось без сюрпризов. Экспорт ведется в специальном формате LAR, который является обычным зипником с кучей XML. А проблема в том, что никакой логики в этих XML не наблюдается. Каждый тип конфигурации, каждый тип данных и прочее переводится в XML по-своему! Причем в этом XML такое количество постоянно меняющейся и зависящей от окружения служебной информации, что их мерж оказывается просто невозможным. Так при импорте одинаковой конфигурации с двух разных серверов получается результат различный на 90%.


Проблему конфигурации Liferay решаем пока просто хранением готового LAR-файла. Мержить его невозможно, но можно хотя бы версионировать изменения и откатываться за минуты.
Особенные трудности доставляет то, что в портлетных технологиях считается большим плюсом. Дело в том, что сам Liferay — это отдельное Java веб-приложение. А все портлеты должны быть оформлены как другое отдельное веб-приложение. Это значит, что контексты, класслоадеры, сессии, реквесты и прочее у них разные. Это приводит к куче проблем как при использовании Spring, так и при попытке сделать некоторые базовые вещи, которые можно было бы использовать во всех портлетах. Liferay эту проблему еще и усложняет, добавляя черную магию (постоянную подмену класслоадеров), то копируя, то не копируя параметры реквестов и сессий из приложения в приложение и изменяя код портлетов при деплое.
В общем, Liferay подготовил нам немало приключений, но большинство из них было возможно решить за счет предоставленных точек расширения и большого сообщества вокруг платформы.

Выводы


Решение Liferay еще не вышло в полноценный продакшн, но кое какие-то выводы можно сделать:

  1. Liferay — мощный инструмент для построения как внутренних, так и массовых порталов.
  2. Liferay позволил решить поставленные перед нами задачи без дополнительных капитальных вложений в разработку своего «велосипеда».
  3. Liferay — система, позволяющая делать защищенные, нагруженные и богатые функционалом решения настолько гибко, насколько это возможно.


Несмотря на все это, есть что улучшить. В ближайшее время планируем сделать исследование по следам полученного опыта, чтобы выяснить, есть ли еще какие-нибудь решения того же класса, помогающие решить задачу проще/правильнее. Если есть варианты — прошу в комментарии, будем благодарны.

Всем спасибо за то, что дочитали статью до конца. Надеюсь, она была достаточно интересна.

© Habrahabr.ru