Привет, Хабр! Меня зовут Сергей Рабинович, я руковожу производственным отделом департамента e-commerce в одной крупной российской ИТ-компании. Периодически я общаюсь с заказчиками, которые самостоятельно внедряют или развивают высоконагруженные интернет-магазины. Большинство из них сталкиваются с двумя вопросами на этом пути:

  • как предусмотреть все нюансы и узкие места, чтобы через полгода при росте бизнеса не столкнуться со сбоями;

  • как решать проблемы при разработке и поддержке, а в идеальной вселенной – даже их предупреждать.

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

От витрины товаров до маркетплейса с миллионами покупателей

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

Таким образом, высокая нагрузка – это ситуации, когда ресурсные мощности не справляются с обработкой входящих запросов. Какая именно это нагрузка, совсем неважно. Это может быть 10 очень «тяжелых» запросов, которые «перемалывают» большой объем данных и «вешают» систему, или 10 миллионов маленьких, которые забивают сетевой канал. И то, и другое – высоконагруженный проект. И кстати, оба примера – повод задуматься об оптимизации, но об этом позже.

Еще 10-15 лет назад интернет-торговля осуществлялась преимущественно в онлайн-витринах, разработанных на базе CMS. Покупатели использовали их как каталоги, а сами заказы совершали через письма на почту или звонки менеджерам. Движок таких онлайн-площадок не позволял выдерживать высокие нагрузки, но их и не было в большинстве случаев.

Вот так раньше выглядело оформление заказа в интернет-магазине
Вот так раньше выглядело оформление заказа в интернет-магазине

Позже такие e-commerce площадки разрастались инструментами приема и обработки заказов. Однако всё равно функциональность была примитивной: не было полноценного личного кабинета, остатки не отслеживались, статусы не обновлялись. Чтобы узнать хотя бы минимальную информацию о своей покупке (например, дату получения) пользователю приходилось звонить или писать на email сотрудникам магазина. Поэтому единственные, кто испытывал хоть какие-то скачки нагрузки, – это менеджеры компаний.

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

  • полноценный личный кабинет с историей заказов и документацией (чеками, счетами и актами);

  • статусы заказа и отслеживание покупки (от РЦ до передачи курьеру);

  • онлайн-оплата;

  • оформление доставки курьером или самовывоза из склада, пункта выдачи заказов;

  • раздел «Избранное»;

  • история поиска;

  • список похожих\рекомендуемых товаров;

  • мгновенные покупки (в несколько кликов).

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

Всё это накладывает на ИТ-архитектуру интернет-магазинов определенные требования и ограничения, технически усложняет решение. Стандартными инструментами, такими как CMS (Wordpress, CS-Cart, ModX) или онлайн-конструкторы (Wix, Ecwid, Tilda), уже не обойтись – они попросту не решают всех задач, связанных с хранением и передачей такого объёма информации о пользователях и ассортименте. Настала эпоха серьезных промышленных систем, способных выдержать такие высокие нагрузки.

От простой ИТ-архитектуры до микросервисов

Представим небольшой локальный бренд одежды, который работает исключительно на рынок Санкт-Петербурга и даже не задумывается о том, что когда-нибудь сможет продавать по всей стране. Компания создаёт интернет-магазин, предварительно оценив, что охваты могут достигать миллиона пользователей, а среднее количество посетителей  – порядка тысячи ежедневно. С этими вводными запускается проект. Спустя пару лет активного роста компания выходит на федеральный уровень – число одновременных запросов в интернет-магазине вырастает до 10 тысяч в минуту. И тут начинаются проблемы – система начинает «тупить» и «валиться».

В этой ситуации первое, что делает команда, – пытается оптимизировать узкие места проекта: переписывает запросы к БД и отдельные участки кода, пересматривает логику работы. Если это не помогает (или параллельно с этими действиями), начинает апгрейдить сервера: добавляет память, меняет процессор и диски – это дает фору. Если и это не привело к желаемому результату, ИТ-команда увеличивает количество серверов, дублирует узлы системы, ставит балансировщик нагрузок, который перераспределяет запросы, делит базу данных на шарды, создает реплики, чтобы облегчить нагрузку. Словом, начинается бег наперегонки с трафиком.

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

Спустя время новая нагрузка (например, сезонные промо «Чёрной пятницы» или акции в канун гендерных праздников) начинает «валить» и эту систему. Компании ничего не остаётся, кроме как делить данные и бизнес-процессы по сегментам – стандартный путь от монолита к микросервисной модели.

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

  1. Базовая ИТ-архитектура. Для простых задач бизнес обычно выбирает архитектуру решений без оглядки на большие нагрузки, часто стараясь на этом сэкономить.

  2. Программная оптимизация. У интернет-магазина есть проблемы в отдельных функциях (например, медленно открываются страницы, или в пиковые нагрузки сайт «вываливается в ошибку»), и ИТ-отдел решает их с помощью оптимизации: добавляет индексы, переписывает запросы и код, добавляет кэширование.

  3. Вертикальное масштабирование («ввысь»). Более сложные задачи требуют серьезных ресурсов – команда увеличивает вычислительные мощности, добавляет память и дисковое пространство. Словом, происходит апгрейд существующей инфраструктуры.

  4. Горизонтальное масштабирование («вширь»). Его выбирают, когда существующие ресурсы уже «не тянут». ИТ-отдел запускает новые сервера, дублирует сервисы и распределяет между ними нагрузку.

  5. Внедрение микросервисов. Это сложный и затратный путь, но он дает самые впечатляющие результаты. Правда, ценой немалых усилий.

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

Переход с одного этапа на другой происходит по двум причинам:

  • компания достигает потолка в оптимизации: система все равно «падает», или «тормозит»;

  • выбранная модель оптимизации становится экономически невыгодной.

Например, в какой-то момент бизнес видит, что расширение и добавление новых ресурсов при росте «ввысь» обходится слишком дорого (обычно цена растет по экспоненте), и тогда он принимает решение расти «вширь». Но при росте продаж и этот этап в какой-то момент достигает точки, когда становится нерентабельно идти по этому пути – компания переходит к более радикальным решениям, например, перестройке архитектуры на микросервисы.

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

Как предугадать перегрузки интернет-магазина

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

Регулярно мониторьте нагрузку

Если у вас разросшаяся ИТ-инфраструктура интернет-магазина, то системы мониторинга нагрузки – не прихоть, а необходимость. Чтобы использование этого инструмента было эффективным, важно, во-первых, выстроить регулярное наблюдение за показателями, а во-вторых, заранее определить «пороговые» значения всех параметров и настроить оповещение при их достижении. Если показатели на мониторинге приближаются к этим критическим отметкам в обычные, а не акционные дни, то, скорее всего, уже поздно что-то исправлять. Необходимо заранее предпринимать меры, когда нагрузка в пределах допустимых значений, но при этом заметна динамика ее роста.

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

Панель мониторинга нагрузки
Панель мониторинга нагрузки

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

Поэтому полезно следить за графиком успешно обработанных запросов. Если видите, что часть запросов просто «отваливается», это значит, что вы теряете клиентов.

Собирайте инсайты от пользователей

Не пренебрегайте платформой для работы с обратной связью. Чтобы захватывать фидбек от пользователей, используйте вспомогательные инструменты (лучше сразу несколько, чтобы у клиентов было больше возможностей сообщить вам об ошибках). Это могут быть:

  • кнопка-виджет (при нажатии появляется форма со смайликами и полем для ввода текста);

  • опросы (инструмент для «точечной» работы, чтобы узнать, хватает ли пользователям информации, легко ли совершить заказ и пр);

  • появляющаяся форма (с ее помощью можно самому инициировать начало диалога с клиентом, главное – задавать правильные вопросы в нужное время, например, сразу после оплаты или оформления заказа);

  • социальные сети и боты в мессенджерах.

Также хорошая идея – соединить качественную и количественную информацию, интегрируя сервис с Google Analytics и «Яндекс.Метрикой». Это простой способ проводить юзабилити-тестирование сайта: сначала получаете фидбек о проблеме, а потом – воспроизводите все, что делал пользователь перед тем, как его оставить.

Сбор инсайтов особенно полезен тем, что если у пользователей возникают сложности с вашим сервисом, которых вы не замечали ранее, вы обязательно о них узнаете и сможете исправить.

Автоматизируйте рутинные процессы

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

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

Тестируйте всё

Если компания разрабатывает свои решения и мало уделяет внимания тестированию, скорее всего, большинство релизов будет просто отваливаться. Несмотря на очевидную пользу испытаний кода, это требует ресурсов, на которые бизнес не всегда готов (хотя опытные разработчики  всегда держат эту опцию в голове). Задача ИТ-руководителя убедить собственников бизнеса в том, что тестирование – это часть продукта, которая влияет на выручку.

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

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

Еще один кейс – проект, над которым работали сразу несколько независимых команд. Сложность была в том, что когда одна группа программистов вносила изменения в свою подсистему, другая – «наслаждалась» серией критических ошибок в своей части. Мы внедрили на проекте автотестирование и написали на старте всего около 30 интеграционных тестов, покрывающих критически важные точки, и стабильность продукта возросла в разы. Релизы больше не вводили команды в ужас предстоящей отладки и поиска ошибок. После такого результата ИТ-подрядчики тоже начали использовать автотесты как часть разработки, а заказчик изменил свое мнение относительно этого инструмента и его практической пользы.

Налаживайте доверительные отношения между бизнесом и ИТ

Противостояние между бизнесом и ИТ-подразделением действительно не редкость. Айтишники – во многом перфекционисты, хотят сделать как лучше, но часто это дорого для компании. Бизнес же в свою очередь старается сэкономить, иногда не совсем оправдано.

Замечал, что в ситуациях, когда ИТ-подразделение возглавляет бизнес-ориентированный человек, такая проблема не стоит. Как правило, такой руководитель понимает, в каких моментах достаточно просто «подкрутить», а в каких – требуется кардинальное изменение. И ценно, когда он видит это заранее и умеет донести ценность до владельцев бизнеса.

Обеспечьте безопасность разработки

На пути масштабирования интернет-магазина и совершенствования его архитектуры программисты неоднократно переписывают код, меняют компоненты решения и взаимосвязи между ними. Если не проектировать отказоустойчивость, бизнес рискует оказаться в ситуации, когда при изменении одного элемента системы «падает» вся платформа. Поэтому правильнее на старте проектировать интернет-магазин с вероятностью, что при обращении одного компонента к другому, тот будет недоступен или в ответ вернется непредвиденная ошибка. Это и есть «безопасное программирование» – стремление предусмотреть любое нештатное поведение подсистем.

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

Своевременно «выкупайте» технический долг

Развиваясь и проходя через все этапы модернизации архитектуры, интернет-магазин претерпевает значительные изменения в технической части: в коде, системах кэширования и хранения. Часто программисты работают в оперативном режиме, потому что бизнес хочет получить всё и сразу, стремится скорее начать зарабатывать больше денег. В таких условиях ИТ-отделу приходится выбирать между качеством и количеством, расставлять приоритеты. Всё, на чем он сэкономит, можно смело записывать в технический долг проекта, который рано или поздно нужно будет всё равно восполнить. Важно сохранять баланс между таким долгом и новыми требованиями бизнеса, которые нужно реализовать «прямо сейчас». Перевес в сторону первого снижает доход компании, а в случае второго – приводит к снижению качества решения, в долгосрочной перспективе – падению выручки. Важно уметь договариваться об этом с бизнесом.


Подведем итог. Чтобы реализовать высоконагруженный e-commerce проект, необходимо следовать простым правилам:

  1. проектировать систему масштабируемой и отказоустойчивой;

  2. не заниматься преждевременной оптимизацией;

  3. внимательно отслеживать «пороговые» значения метрик, чтобы вовремя реагировать;

  4. автоматизировать и тестировать всё, что можете;

  5. собирать обратную связь;

  6. наладить прозрачную коммуникацию между бизнесом и ИТ-командой;

  7. не забывать о техническом долге.

Надеюсь, в этой статье вы узнали что-то новое. Если у вас есть вопросы или замечания – жду вас в комментариях. ;)

Комментарии (6)


  1. BugM
    19.11.2022 02:01
    +2

    Какие микросервисы на масштабе поставили второй сервер и нормально заработало? Поставьте 10 серверов, превентивно за пару недель до распродаж. И про БД не забудьте, слейвов там добавьте с запасом и перенесите запросы на них или что там у вас. Это стоит копейки и не требует примерно ничего.

    Зачем это все? Обычная балансировка нагрузки от клиентов справляется примерно со всем, если код нормально написать.


    1. angelrsa Автор
      20.11.2022 13:53

      Всё верно, об этом и статья - всё нужно делать с умом и вовремя - ищем узкое место и работаем над ним, а не сразу со старта "а давайте сделаем микросервисы". Иначе потратим миллионы денег и тысячи часов работы на то чтобы сделать микросервисы потому что кто-то их очень захотел ("модно", или "у других есть, мне тоже надо"). А на самом деле всё это сейчас не нужно, и эти ресурсы можно было бы пустить в другое русло, более важное и нужное на данном этапе.


      1. AirLight
        20.11.2022 23:36

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


        1. BugM
          20.11.2022 23:40

          Распределенные транзакции. Отказоустойчивость. Распределенные логи. Распределенный трейсинг. Распределенное профилирование.

          Мелочи.


    1. AirLight
      20.11.2022 23:33

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


      1. BugM
        20.11.2022 23:38
        +1

        Случаи они любые бывают, не сомневаюсь.

        Если у вас такая нагрузка на запись в SQL БД, то вы что-то делаете не так. Я в этом уверен на 100%. Вероятнее всего момент когда пора было ставить рядом какую-то другую БД и писать в нее то что не надо писать в sql бд был упущен какое-то время назад. И теперь придется с болью и страданием все переписывать.

        У типичного, пусть даже большого, магазина нет такой нагрузки на запись в sql бд чтобы с ней какое-то обычное железо не справилось. Вы не Амазон. При чем тут монолит я вообще не понял.