Может ли команда разработки быть спокойной 8 марта, если вы в сервисе №1 по доставке цветов? Наша история.
Меня зовут Дима, я работаю техническим директором в Flowwow. Мы развиваем маркетплейс локальных магазинов, которые продают красивые букеты и подарки. В нашей R&D команде сейчас 30 разработчиков, и мы используем обширный стек технологий — условно, от Ansible до Kotlin.
У нас есть несколько ключевых дат, в которые количество продаж взлетает на порядок — День матери, 14 февраля и 8 марта. Мы научились проходить эти периоды почти безболезненно и с технической стороны, и со стороны бизнесовой: «уровень негатива» пользователей в пики находится на уровне любого обычного дня, а техническая команда не поднимает упавшую платформу.
Как и у любого процесса, у нашего тоже есть предыстория.
Как проходят праздники для Flowwow?
Сейчас в обычный день у нас около 3 500 заказов. Главные “цветочные” праздники в году – День матери, 14 февраля и 8 марта – означают для нас рост числа покупок в 10, 15 и даже 20 раз. Здесь же учитываем, что и среднее количество заказов в день увеличивается в 2-3 раза ежегодно.
Важный момент – не только быстро масштабироваться, но и быстро снижать обороты после прохождения пика. Так, в 2022 году мы заметили интересную динамику: если предыдущие два года пользователи заказывали подарки и букеты накануне праздника, то в этом году большее количество заказов происходило день в день. Такой эффект, конечно, срабатывает как дополнительная нагрузка.
И хотя пиковые нагрузки в нашем случае легко прогнозируемы, мы не всегда умели готовиться к ним как следует. Вот два тому примера:
14 февраля 2017 года
Мой отпуск: Домбай, горы, я на высоте 3 000 метров ловлю свежий воздух и сигнал, чтобы быть на связи, ведь мы с командой спасаем падающие от нагрузки серверы. А тогда было всего 3K заказов за 2 дня, что в 13 раз меньше, чем на последнее 14 февраля.
День матери 2020 года
Праздник внезапно стал популярнее в стране, и наш сервис стал популярнее — все сошлось. Предыдущие годы трафик на День матери рос не больше чем в 2 раза, а в 2020 году увеличился в 7 раз. Мы оказались не готовы к такому всплеску – ни морально, ни физически. В итоге мы справились, но это стоило выходных и сна всей команде разработки: в пятницу накануне праздника я ушел с работы в два ночи, следующие два дня мы также трудились – поддерживали и чинили платформу в экстренном режиме.
Опыт не прошел даром – мы поняли, что теперь есть еще один бизнесовый пик в году и те работы, которые раньше стартовали в январе (перед 14 февраля и 8 марта), стали запускать уже в октябре. С тех пор ноябрь мы встречаем во всеоружии.
Как подготовиться к пику?
Мы разделяем подготовку к пиковым периодам на три направления:
поиск узких мест и оптимизация текущей инфраструктуры;
помощь команде поддержки;
масштабирование серверов.
Оптимизация приложения
При подготовке к пикам первым делом мы анализируем наше приложение, потому что в другие периоды мы так сконцентрированы на скорости разработки продукта, что до оптимизации не всегда доходят руки. Как правило, выявляются следующие пункты на улучшение:
медленные запросы к базе данных или большое их количество,
сложная логика на уровне приложения,
медленная работа сторонних приложений, с которыми идет обмен данными.
Внутри мы формируем отдельную команду разработчиков, которую освобождаем от бизнес-задач и даем возможность заниматься только оптимизацией кода приложения и запросов баз данных. Обычно на оптимизацию уходит месяц до пикового события. Тут хорошо работает принцип Парето: оптимизация 20% самых узких мест закрывает 80% проблем с производительностью, которые можно решить в коде и в базе данных.
Вообще получается удобно: начинаем оптимизировать в октябре под День матери (последние выходные ноября), потом пик 14 февраля как генеральная репетиция и 8 марта – премьера сезона. Как правило, “оптимизационного заряда” в это время нам хватает, и мы спокойно живем до октября следующего года.
Помощь команде поддержки
Параллельно команда разработчиков, которая сфокусирована на развитии админки, идет к команде поддержки и просит указать на самые слабые места в работе с клиентами и партнерами — какую функциональность добавить в чат, какие кнопки вывести в карточки товаров? Поддержка выражает все свои пожелания.
В этом году наша админка получила такие маленькие, но важные обновления:
Оптимизация информации о каждом заказе (краткие сведения о составе заказа, доставке и ее стоимости);
Автоматический расчет примерного времени, за которое курьер доберется до магазина и затем от магазина до клиента;
Фильтр заказов по городам и странам;
Возможность для продавца пожаловаться на отзыв от клиента – в сам день 8 марта это не так актуально, зато уже на следующий день можно разобрать спорные ситуации и поддержать репутацию магазинов, если случилась ошибка.
Масштабирование серверов
Начну с того, как мы масштабировались раньше (и почему это не лучшее решение): мы просто клонировали сервера из образа диска и уводили на копии часть трафика. Плюсы клонирования – это скорость развертывания, но это работало, пока нам хватало пяти серверов. Кроме того, такой метод не предполагает обновления рабочих станций с точки зрения безопасности и производительности. То есть, клонируя сервер, который был конфигурирован в 2017 году, мы получаем зоопарк серверов, современных с точки зрения 2017 года. Также есть и другие ограничения: например, Amazon выпускает сервера на ARM-процессорах, которые эффективнее и дешевле старых на 30%, а операционку из 2017 года на них запустить уже нельзя.
Как мы делаем сейчас: мы описали всю инфраструктуру через IaC, infrastructure as Code. При необходимости запуска дополнительного сервера мы стартуем не клон, а просто новый сервер по нужной нам конфигурации, заливаем данные – и можно давать трафик. На полный переход и описание инфраструктуры у нас ушло около года, но результат стоит того. Здесь нет ограничений по количеству запусков, а еще мы смогли поменять технологический стек с Intel на ARM, используя подход IaC.
Как мы определяем, сколько серверов потребуется под пиковые нагрузки? Во-первых, у DevOps есть статистика за прошлые пики, от которой можно отталкиваться при планировании (условно: какой был rps и какой серверной группировкой мы все это вывезли). Во-вторых, мы спрашиваем у маркетинга, сколько планируется трафика, затем добавляем к этим цифрам 50% в качестве страховки и решаем, сколько серверов и какой мощности нужно запустить.
Что изменилось весной 2022
Этот год можно рассматривать как отдельный кейс. Во-первых, резко изменилось поведение клиентов (я это упоминал в начале статьи): вместо того, чтобы заказать цветы заранее с указанием даты доставки 8 марта, большинство пользователей сделали заказ день в день. Уровень нагрузки, на который мы рассчитывали, был превышен – пригодился тот самый резерв +50% к плану.
Во-вторых, с конца февраля появились дополнительные вызовы:
DDoS-атаки;
возможный уход вендоров – поставщиков услуг и сервисов для онлайн продуктов;
блокировки сервисов и риск оказаться в суверенном рунете.
К кибератакам мы были готовы: нас пытаются сломать при каждом пике, поэтому мы заботимся о надежной защите. В последние два года мы систематически проводим аудит безопасности и исправляем найденные уязвимости в серверах и в нашем коде, чтобы не думать об этом в момент подготовки к высоким нагрузкам.
Были вполне логичные опасения, что Github или Amazon приостановят работу с Россией, поэтому мы в срочном порядке сделали бэкапы всех данных и пользовательского контета на отчественных облаках. Если бы наш основной дата-центр стал недоступен, мы бы смогли запуститься на Яндекс.Облаке за пару дней.
Наконец, мы осознали, что даже если иностранные компании не разорвут отношения с российскими клиентами, иметь критичные узлы IT-инфраструктуры за пределами РФ слишком ненадежно. Поэтому после срочного бэкапа данных мы начали планомерно дублировать критичные узлы в российском дата-центре. Сейчас мы имеем полностью рабочие контуры и в РФ, и за пределами РФ, а между ними налажен информационный обмен, чтобы все работало как единое целое.
Можно представить такой таймлайн готовности:
за две недели до дня Х — включаем на низкую мощность все дополнительные сервера, чтобы понаблюдать за ними подольше; составляем график дежурств: есть DevOps, один инженер команды нагрузки, один инженер для поддержки.
за три-четыре дня до дня Х — объявляем фича-фриз на изменения в продакшене (по мобильным приложениям фича-фриз наступает минимум за неделю). Все решения зарелизили, даем им время настояться: как они будут себя вести, какие ошибки будут выдавать? Здесь же запускаем на полную мощность дополнительные сервера.
за день до дня Х — финально проверяем готовность всех систем и команды.
В день Х работает выбранная смена, система мониторингов собирает информацию о нагрузке, трафике, ошибках. Если что-то пошло не так — есть регламент, по которому DevOps и инженеры нагрузки реагируют на ошибки и принимают решения. Ботам мы поручаем следить за аномалиями, все и всё при деле.
Почему масштабирование заранее — это хорошо
Прошел пиковый период, и мы не только выдохнули, но и подумали на будущее. DevOps фиксирует базовые параметры, которые позволяют его пройти — трафик, число заказов, количество серверов и репликаций. Это позволяет нам строить прогнозы и оценивать мощности для нового периода.
Сейчас мы испытываем почти столько же радости, сколько и получатели цветов и подарков. Вот данные по итогам крайнего пика – 8 марта 2022:
процент опозданий курьеров не выходил за рамки 7,5% (а опозданием мы считаем даже задержку на 5-10 мин),
уровень негатива (оценка 3 и ниже по пятибалльной шкале) составил всего 3,5 %;
количество споров, где понадобилось участие нашей поддержки, оказалось меньше на 200 обращений, чем в прошлом году (тогда как количество заказов возросло на 26 тысяч).
Плюс ко всему, мы можем не работать всей командой в пиковые выходные, а заранее договориться о сменах. Это правда важно.
Буду рад, если поделитесь в комментариях, как вы решаете вопрос масштабирования. А еще было бы очень интересно почитать про кейсы из практики, когда нагрузка оказывалась в разы больше запланированной: обычно такие ситуации – кладезь нестандартных решений.