Привет!

Меня зовут Михаил, я заместитель директора по ИТ в компании «Спортмастер». Я хочу поделиться историей о том, как мы справились с трудностями, возникшими во время пандемии.

В первые дни новых реалий привычный формат офлайн-торговли «Спортмастера» замер, и нагрузка на наш онлайн-канал, в первую очередь в части доставки на адрес клиенту, возросла в 10 раз. За несколько недель мы трансформировали гигантский по объему офлайн-бизнес в онлайн, адаптировали сервис под потребности наших клиентов.

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

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

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

Эксплуатация онлайн-сервисов

Колесников Сергей, отвечает за эксплуатацию интернет-магазина и микросервисов

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

Количество заказов с 18 по 31 марта
Количество заказов с 18 по 31 марта
Количество запросов к микросервисам онлайн-оплаты
Количество запросов к микросервисам онлайн-оплаты
Количество оформленных на сайте заказов
Количество оформленных на сайте заказов

На первом графике мы видим, что прирост составил примерно 14 раз, на втором — 4 раза. Наиболее показательной при этом мы считаем метрику времени ответа наших приложений. 

На этом графике мы видим ответ фронтов и приложений, и для себя мы определили, что как такового роста мы не заметили.

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

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

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

В какой-то момент мы подумали и решили, что хватит это терпеть — нам нужна единая система, чтобы видеть всю картину полностью. Основные технологии, которые входят в наш стек, это Zabbix как центр алертинга и хранения метрик, Prometheus для сбора и хранения метрик приложений, Stack ELK для логирования и хранения данных всей системы мониторинга, а также Grafana для визуализации, Swagger, Docker и другие полезные и знакомые вам штуки.

При этом мы используем не только доступные на рынке технологии, но и разрабатываем кое-что самостоятельно. Например, мы делаем сервисы для интеграции систем друг с другом, то есть некое API для сбора метрик. Плюс работаем над собственными системами мониторинга — на уровне бизнес-метрик мы используем UI-тесты. А также бот в Telegram для оповещения команд.

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

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

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

Технические испытания 

Орлов Сергей, руководит центром компетенции веб- и мобильной разработки

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

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

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

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

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

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

Третий кит — это CI/CD Pipeline. Процессы сборки, тестирования, развертывания приложения должны быть максимально автоматизированы, здесь не должно быть ручных вмешательств. Тема CI/CD Pipeline достаточно глубока, и я затрону ее только вскользь. Стоит упомянуть только, что у нас есть чеклист CI/CD Pipeline, по которому с помощью центров компетенции проходит каждая продуктовая команда.

А вот и чеклист
А вот и чеклист

Таким образом достигается очень много целей. Это версионирование API, и feature toggle, чтобы избежать паровоза релизов, и достижение покрытия разных тестов такого уровня, чтобы тестирование было полностью автоматизировано, деплои были бесшовными и прочее.

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

Во-первых, надо выбирать специализированные инструменты под конкретные задачи. Да, звучит очевидно, и понятно, что гвозди забивать стоит молотком, а наручные часы разбирать специальными отвертками. Но в наш век многие инструменты стремятся к универсализации, чтобы охватить максимальный сегмент пользователей: базы данных, кеши, фреймворки и остальное. Вот, например, если взять базу данных MongoDB, она работает с мультидокументарными транзакциями, а база данных Oracle работает с json-ми. И казалось бы, что все можно использовать для всего. Но если мы ратуем за производительность, то нам нужно четко понимать сильные и слабые стороны каждого инструмента и использовать нужные нам для нашего класса задач. 

Во-вторых, при проектировании систем каждое повышение сложности должно быть обоснованным. Мы должны постоянно держать это в голове, принцип low coupling всем известен. Я считаю, что его нужно применять и на уровне конкретного сервиса, и на уровне всей системы, и на уровне архитектурного ландшафта. Также важна способность к горизонтальному масштабированию каждого компонента системы на пути нагрузки. Если обладать этой способностью, масштабирование не составит никакого труда.

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

Кеши

Необходимо осознанно подходить к выбору локальных и распределенных кешей. Иногда имеет смысл использовать и те, и другие в рамках одной системы, Например, у нас есть системы, в которых часть данных по сути является витринным кешем, то есть источник обновлений находится за самой системой, и системы эти данные не меняют. Для такого подхода мы используем локальный Caffeine Cache. 

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

Кроме того, смена сериализатора на Kryo в Hazelcast дала нам неплохой прирост. А переход от  ReplicatedMap к IMap + Near Cache в Hazelcast позволил нам минимизировать движение данных по кластеру. 

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

Реактивный стек

Мы используем реактивный стек в уже достаточно большом количестве систем. В нашем случае это Webflux или Kotlin с корутинами. Особенно хорошо реактивный стек заходит там, где мы ожидаем медленные input-output операции. Например, вызовы медленных сервисов, работа с файловой системой либо системами хранения.

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

Старайтесь обращать ошибки в собственные runtime exception. Реальный поток выполнения программы отходит к реактивным фреймворкам, выполнение кода становится нелинейным. Как следствие, очень сложно диагностировать проблемы по стек-трейсам. И решением здесь будет создание понятных объективных runtime exception-ов на каждую ошибку.

Elasticsearch

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

Не используйте postfilter без необходимости. При больших данных в основной выборке эта операция очень сильно грузит базу данных. 

Используйте bulk-операции там, где это применимо.

API

При проектировании API закладывайте требования к минимизации передаваемых данных. Особенно это актуально на связке с фронтом: именно на этом стыке мы выходим за каналы наших ЦОДов и уже работаем на канале, связывающего нас с клиентом. Если на нем есть малейшие проблемы, слишком высокий трафик вызывает негативный user experience.

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

Организационная трансформация

Ерошкина Елена, заместитель директора по ИТ

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

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

По счастливой случайности основная часть таких продуктовых команд у нас как раз находилась в области онлайн и омниканальных сервисов. Это позволило нам в кратчайшие сроки (серьезно, буквально за два дня) перейти в режим удалённой работы без потери эффективности. Настроенный процесс позволил быстро адаптироваться к новым условиям работы и выдержать достаточно высокий темп поставки новой функциональности.

Кроме того, у нас возникла необходимость усилить те команды, которые находятся на фронтире онлайн-бизнеса. В тот момент стало понятно, что мы можем это сделать только за счет внутренних ресурсов. И порядка 50 человек за две недели сменили область, где они работали до этого, и встроились в работу над новым для них продуктом. 

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

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

Ясное дело, что при удалённой работе и высоком темпе изменений, когда от участия каждого зависят бизнес-показатели, нельзя полагаться только на внутренние ощущения из серии «А всё ли у нас идёт хорошо? Да вроде неплохо». Необходимы объективные метрики производственного процесса. Такие у нас есть, они доступны каждому, кто интересуется метриками продуктовых команд. Прежде всего самой команде, бизнесу, смежникам и руководству.

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

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

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

Я думаю, что сложившаяся ситуация открывает для нас такие возможности  и перспективы, которые, возможно, мы и сами пока ещё до конца не осознаём. Но тот опыт и та практика, которую мы получаем прямо сейчас, подтверждает, что мы выбрали правильный путь развития, не упустим в будущем эти новые возможности и сможем так же эффективно отвечать на те вызовы, которые будут стоять перед «Спортмастером».

Выводы

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

Люди. Это то, на чем всё и держится. Сотрудники должны получать удовольствие от работы, понимать цели компании и цели продуктов, которыми они занимаются. И, конечно же, могли профессионально развиваться. 

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

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


В общем, примерно так и выжили. Основной тезис современности подтвердился ещё раз, звонко щелкнув по лбу

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

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