Миссия выполнима: глобальный продукт без простых задач

Меня зовут Евгений Моспан, и я в IT с 2003 года. Начинал стажером в продуктовой компании, и за время работы там прошел путь от интерна до исполнительного директора. Когда челленджи в компании закончились, я перешел в ЕРАМ, чтобы разрабатывать продукты для заказчиков из крупного международного бизнеса. Моя роль роль — Solution Architect — как нельзя лучше подходит для инженера. Сегодня я расскажу о своем опыте работы над одним из таких продуктов.

Один из крупных клиентов ЕРАМ — логистическая компания, функционирующая в более чем 220 странах и территорий по всему миру. End-to-end продукт, над которым мы работаем, должен заменить все ее многочисленные front-office системы на одну современную, быструю и понятную пользователям. Система включает несколько тысяч полноценных Use Cases и при этом должна быть гибкой как в плане статического контента, так и бизнес-правил, которые сильно отличаются в зависимости от стран. Более 10 команд были распределены по ряду локаций.

Глобальный проект — это огромная ответственность

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

Компоненты имплементированы с помощью Play! Framework, Spring MVC, Adobe Experience Manager (AEM), есть компонент на слое баз данных, компонент для логирования и так далее. Front-end инженеры работают в основном с Angular JS; Back-end — помимо Spring, Play, AEM — должны ориентироваться в Quartz Scheduler, Terracotta; DBA-инженеры работают с базами данных Oracle. Есть также DevOps-ы, которые автоматизируют деплоймент с помощью Ansible.

На проекте с таким широким спектром технологий успешно работать могут только подготовленные и технически подкованные Solution Architects (SA) и Delivery Managers (DM). Архитектор должен понимать, куда какая функциональность будет добавлена и как это повлияет на систему в глобальном контексте. Delivery Manager, в свою очередь, должен правильно организовать работу распределенных команд и не допустить, чтобы они блокировали друг друга. Вообще, связка SA-DM на этом проекте очень плотная, так как надо постоянно быть on the same page и следить, чтобы все компоненты были развернуты в нужном объеме, нормально масштабировались и так далее.

С точки зрения архитектуры на проекте есть много quality-атрибутов, которые наш заказчик попросил учесть. Задача непростая, так как их сложно даже увязать между собой из-за возникающих противоречий. Например, клиент просит, чтобы перформанс приложения был end-to-end не более трех секунд. Это означает, что вся сложная функциональность и ее конфигурация должна быть уложена в эти три секунды. При этом, помимо системы, которую разрабатывает ЕРАМ, у заказчика есть еще множество других систем, с которыми интегрируется наш проект и с которыми надо считаться.

Или есть еще один quality-атрибут — доступность приложения по всему миру 24/7 и определенные ограничения по развертыванию. У клиента есть собственные data-центры, в которых и должны деплоиться приложения, а между ними должна быть реализована active-active репликация для обеспечения failover. Чтобы удовлетворить это требование, нам надо реплицировать огромные объемы данных фактически в режиме реального времени, что накладывает свои ограничения на базу данных и на то, как она должна быть спроектирована.

Вызовы мотивируют нас

Например, Play! Framework, который мы используем в одном из компонентов, не только дает реактивный подход к написанию бизнес-логики «из коробки», но и вносит сложности в имплементацию функциональности. Логика у нас последовательная, так как бизнес интересует end-to-end транзакция, а реактивный подход как раз предполагает событийную модель, поэтому инженерам и архитекторам пришлось придумывать способы, которые позволяли бы использовать преимущества реактивного подхода и в тоже время адресовать бизнес-цели, которые ставятся перед той или иной транзакцией. Отдельным вызовом было свести воедино Play-фреймворк и Spring Security, Spring Integration, Spring Cashable, Spring Data и другие фреймворки этой экосистемы, которые мы активно используем на проекте.

Что касается интерфейса пользователя, то мы довольно долго искали золотую середину между тем, что должно покрываться непосредственно платформой по управлению контентом (AEM), а что должно было быть бизнес-кодом самого front-end приложения, которое имплементируется на AngularJS и изменяется исключительно FE-разработчиками. Такой баланс был достигнут за счет того, что страница была разделена на CMS-компоненты, которые получили названия «транзакционные» и «статические». В итоге контент-авторам был предоставлен доступ только к компонентам последнего типа для управления контентом, который отображался конечному пользователю. Эти требования были довольно жесткими, ведь для разных стран нужен был контент разного формата и направленности. Транзакционные компоненты стали source-кодом самой системы.

В этом продукте нет простых задач в принципе

Любая, на первый взгляд, простая задача становится крайне сложной в глобальном контексте. Например, кэширование первичных ключей в Нibernate — распространенная фича «из коробки», которую многие используют для улучшения перформанса, однако в условиях active-active репликации все не так просто. Она вносит свои требования к формированию первичных ключей, Нibernate — свои и все это надо знать, понимать и кому-то адресовать.

Нам необходима экспертиза во многих областях: человек, который управляет процессом разработки фичи, должен понимать АЕМ и AngularJS, все тонкости и специфику Java и его фреймворков, Нibernate, слой базы данных Oracle... Уложить это в голове одного инженера практически невозможно. Для справки: самый большой use case на этом проекте касался процесса отправки посылки и был описан клиентом на 90 страницах, разбит на почти столько же подкейсов, которые декомпозировали на порядка 1000 stories. За простой, на первый взгляд, работой лежит колоссальный объем функциональности, которая должна чем-то конфигурироваться.

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

Задачи Solution Architect

В таких условиях вовлеченность Solution Architect-а и его тесное взаимодействие с Delivery Manager-ами необходимо на протяжении всего проекта. Архитектура была сформулирована на high level летом 2015 года и с тех пор претерпевала лишь итерационные изменения. В ходе такого огромного проекта оказалось, что не всегда low level дизайн можно поручить тимлидам. Они руководят десяткой команд, в которых разработчики параллельно делают разный функционал и разные бизнес-задачи.

Вопрос: а все ли ребята понимают, что происходит в глобальном масштабе? Ясно, что «сторю» они сделают, а вот как она повлияет на другие stories и наши quality-атрибуты — это понятно далеко не всем.

На все подобные вопросы должен кто-то отвечать. За это взялась группа Solution Architecture, которая, помимо дизайна, сложных функциональных задач, адресования quality-атрибутов, несет своеобразную просветительскую миссию, объясняя, как нужно имплементировать задачи с точки зрения большой и требовательной экосистемы. В группу вошли техлиды, присоединившиеся к компании с рынка, и ребята, которые выросли на этом проекте. Некоторые инженеры решили, что им интересно развиваться в направление архитектуры, и я стал их ментором в рамках программ SA Mentoring и SA School. Постепенно наша команда стала мостом между бизнесом и имплементацией, конвертируя бизнес-требования в технические. Теперь и заказчик интересуется у нас, как любая новая функция повлияет на систему в целом.

С точки зрения масштабов проекта обеспечивать CI/CD довольно сложно, потому SA и DM-ы создали прозрачный процесс, по которому происходит delivery. Любое изменение кода проходит долгий путь от разработки на локальной машине до развертывания в окружении: после разработки девелопер должен покрыть свой код unit интеграционными тестами, чтобы убедиться, что он не сломает процесс CI (разработчиков много, и мы пытаемся минимизировать количество коммитов, которые будут ломать билд). Код также проходит статистический анализ с помощью Sonar, ревью в Gerrit, куда интегрированы чеки от Sonar, запуск unit-тестов и сборка билда, чтобы обойтись без рутины и отсекать явные gap-ы. После того, как код попадает на CI, проходит билд всех артефактов и развертывание системы в целом. На этой системе запускается весь набор интеграционных тестов и Smoke end-to-end тестов от наших автоматизаторов. Если артефакт успешно проходит все quality gates (в которые входят также и требования quality-атрибутов, security, performance issues), а SonarQube не показывает новых issues, то этот артефакт считается зеленым и попадет к QA-инженерам, которые проводят мануальное тестирование фичи и дают рекомендации по автоматизации ее регрессии. Только после этого артефакт готов к развертыванию на следующих энвайронментах. На окружение заказчика мы деплоим его еще во время первой итерации, чтобы убедиться, что ничего не ломаем, а в конце каждого раунда формируем релиз-кандидат по каждой итерации. Важным quality gate является отсутствие critical, blocker и major issues в рамках того кода, что написан. Таким образом, для девелоперов у нас условия достаточно суровые, но это сделано именно из-за осознания масштабности системы.

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

Преодоление сложностей

В процессе разработки нам пришлось преодолеть проблемы с точки зрения архитектуры/delivery и критично важного улучшения скорости работы системы, без которого проект не был бы успешен.

Основное время работы над системой ушло на core-функциональность, в которую входила возможность отправки посылок для частных лиц. Все основные элементы и интеграции мы сделали в рамках этой работы. Заходя в систему, пользователь создавал на сайте кабинет и работал со своими данными, ни с кем ими не делясь. Но компания заказчика сотрудничает не только с частными лицами, но и с корпоративными клиентами. У последних возникают совершенно другие требования: они хотят работать с данными совместно.

Так появилась задача расширить базовую функциональность таким образом, чтобы позволить многим пользователям одной компании-клиента работать в рамках общего кабинета. Требования для этого у заказчика были широкими, потому его клиенты-юрлица находятся по всему миру. Одной из основных была возможность распределения ролей пользователей и доступа в зависимости от их должностей. Ограничений по отправке посылок у заказчика получилось около 200: от суммы, потраченной на доставку, до веса посылки.

Чтобы только собрать все ограничения и проработать то, как они будут интегрироваться в существующую функциональность, архитектурная команда вместе с аналитиками потратила около четырех-пяти месяцев. За это время мы проводили регулярные воркшопы с заказчиком, привлекали стейкхолдеров, систематизировали все, делали дизайн, показывали его драфты заказчику.

После основательной подготовки всю команду нужно было переключить с core-функциональности на работу над новой. Здесь мы столкнулись с серьезным вызовом.

Все команды писали свои конкретные модули. Поэтому нам пришлось готовить базу под то, чтобы мы могли легко пересаживать людей из одного модуля в другой, обеспечив тем самым нужный масштаб для реализации новых требований. Заказчик поставил задачу привлечь всех людей с первого дня. Это примерно так же, как на новом проекте сразу стартовать со 100 человек.

Чтобы подготовиться к этому, мы выделили нескольких сотрудников, которые в течение месяца сделали скелет того, что мы собирались изменить. Это были опытные специалисты, которые могли работать в условиях неопределенности. Они реализовали основные флоу, в которые нужно было вводить функции, которые хотел заказчик.

Когда мы показывали первое демо с результатами работы за месяц, произошла небольшая коллизия. Вечером мы подготовили environment, на котором все уже было настроено и работало, хотя в этот же момент еще идет активная разработка. За 20 минут до начала нужно убедиться, что все готово к презентации, но заготовленная среда не работала. Я понимал, что демо показать не смогу, а со стороны заказчика присутствуют топ-менеджеры и перенести ничего нельзя. Оказывается, что среда, в которую мы установили наше приложение, перезагружается, и когда процесс закончится — непонятно. За пять минут до демо мы смогли локально поднять нужную среду на двух ноутбуках. Новая идея презентации заключалась в том, что мы разделили проект на две части: функциональность — в одной системе, ее настройки — в другой.

Демо прошло успешно. А уже вечером того же дня мы объяснили всем командам, что они должны делать. За день мы вовлекли все команды — более 100 человек. В первый же день они приступили к разработке.

В конце разработки команду ждал еще один вызов

Изначально клиент ставил задачу, чтобы перформанс приложения был end-to-end не более трех секунд. В процессе работы над функциональностью системы, многими вещами жертвовали из-за сроков. Когда же она была закончена, пришло время уделить внимание скорости работы. С точки зрения архитектуры она должна работать быстро, но имплементация некоторых в местах могла ситуацию портить. Когда решение было установлено на предпродакшн-среде, оказалось, что наши основные флоу работали примерно по три минуты.

Никто не понимал в чем было дело. Чтобы найти причину, пришлось вовлечь шесть инженеров, провести множество экспериментов и ввести процесс обработки таких issues.

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

Эта работа была критично важна, потому что многие системы, которые заказчик делал ранее, не могли пройти этап performance-тестирования. Из-за их медлительности бизнес-клиенты не позволяли вводить их в эксплуатацию.

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

Вместо вывода

Хотелось бы обратить внимание на несколько, казалось бы, простых, но, исходя из собственного опыта, очень важных моментов. Когда вы беретесь за большой и сложный продукт, первое, что нужно досконально продумать — как вы будете координировать большое количество людей. Вам нужно всеми силами стремиться к прозрачности информации. Вся она должна находиться в системе контроля версий. Не распространяйте важную информацию и документы по почте, не позволяйте принимать важные решения в чатах и во время отдельных звонков.

Четкая документация и зафиксированные решения дают возможность контролировать версионность и в случае пополнения в команде — давать новым людям не историю чата, а ссылку на конкретный документ. Заведите себе правило: если вы не можете отправить ссылку на артефакт с запрашиваемой информацией, создайте его!

В больших проектах нет простых требований. Всегда нужно прояснять самые мелкие детали: чем лучше они проговорены и описаны, тем меньше шансов на переделку всей работы или значительной ее части. Старайтесь согласовать достаточно четко и критерии «приемки» работы: все участники должны понимать, что означает «задача сделана и проверена стейкхолдерами». Тогда любой продукт будет не только интересен в разработке, но и эффективен после релиза, в реальной жизни.

Похожие статьи:
Три года назад мы публиковали интервью с анонимным разработчиком из ВР. Как обстоят дела с высокими технологиями в главном ведомстве...
Мы уже писали о том, что компания Alcatel готовит к выпуску смартфон Idol 4 Pro под управлением операционной системы Windows 10, а теперь стало...
Офіційні джерела Core Data Guide від Apple. Документація від Apple по Core Data. Початок «Hello Core Data!», — стаття Віктора Амеліна російською...
По слухам, компания Samsung намерена использовать в смартфоне Galaxy S7 20-МП камеру, чтобы ликвидировать «отставание» от...
Мене звати Ірина Ісай, я техрайтерка кіберспортивного медіахолдингу WePlay Esports, частини холдингу TECHIIA. У попередній...
Яндекс.Метрика