Cтатья посвящена проекту «ВсеИнструменты.ру» — крупнейшему интернет-магазину DIY-товаров и нашему клиенту по совместительству. Расскажем, с чего начинали сотрудничество более пяти лет назад, как сейчас обстоят дела и куда мы вместе идём. Поговорим о сопровождавших этот путь технических вызовах и особенностях решений в инфраструктуре, которые позволили бизнесу добиться впечатляющего роста.

«ВсеИнструменты.ру» — изначально онлайн-ритейлер товаров для дома и дачи, строительства и ремонта. С 2006 года активно развивает сеть фирменных торговых точек, а в настоящее время насчитывает более 600 собственных магазинов в 264 городах России и маркетплейс. Численность сотрудников превышает 7000 человек. 93% продаж приходится на онлайн, а это порядка 1000 RPS и ~1 млн уникальных посетителей в день.

Акт первый. Подъём на борт

Когда проект пришёл к нам в 2017 году, это была классическая схема с несколькими виртуальными машинами, каждой из которых отводилась своя роль. Основными компонентами инфраструктуры были:

  • База данных — нестареющий реляционный столп в виде MySQL версии 5.5. Размеры её не превышали 50 ГБ.

  • Backend — сердце приложения на базе Nginx + PHP-FPM 7.0. Было простое масштабирование: если приложение не справлялось с нагрузкой, разворачивалась новая виртуальная машина-клон.

  • Memcache для кэширования данных из СУБД.

  • Sphinx для поиска.

  • NFS — ведь нет более простого способа пошарить код или файлы статики между несколькими машинами.

Команду разработки составляли около 15 человек.

Подведём итог, что имелось по инфраструктуре и процессам её сопровождения на тот момент:

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

  • Системы управления конфигурациями не использовалось.

  • Для хранения статики использовался NFS, смонтированный на ВМ с бэкендом. Забегая вперёд, хочется сказать, что он оказался очень живучим и надолго «прилип» к проекту, решая свою основную задачу, но мешая развитию (ежемесячно требуя жертву в виде инженеро-часов).

  • Распределения или резервирования, предусматривающего наличие больше одного дата-центра, предусмотрено не было.

По разработке:

  • Разработка и тестирование происходили локально. Окружение разворачивалось на машине разработчика с помощью Vagrant и Chef. 

  • Деплой происходил с помощью самописной утилиты. 

  • Миграции и прогрев кэша запускались на сервере вручную исполнителем после деплоя.

Акт второй. Таков путь

Несмотря на кажущуюся простоту и классическую конфигурацию, предстояло решить немало проблем:

  • недостаточная отказоустойчивость инфраструктуры;

  • отсутствие резерва и плана действий в случае проблем с ЦОД;

  • полуручной деплой;

  • сложность поддержки окружения для разработки, приближенной к production;

  • отсутствие автоматического тестирования;

  • деплоится только код, но не инфраструктурные зависимости (просто пакеты в ОС).

Глядя на задачи, стоявшие перед инфраструктурой, мы вскоре пришли к необходимости Kubernetes в проекте и переносу в него приложений. Забегая вперёд: в K8s было перенесено почти всё, с чем проект пришёл к нам, за исключением NFS и MySQL. О том, какие конкретно плюсы принесла миграция, рассказано дальше.

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

Отказоустойчивость

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

Вряд ли нужно рассказывать очевидные вещи о том, что резервирование: 

  • значительно снижает время простоя;

  • даёт больше пространства для манёвров в случае деструктивных плановых работ;

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

  • значительно повышает стоимость инфраструктуры и её обслуживания.

Техническая сторона вопроса на тот момент позволяла нам получить холодный резерв, то есть неактивную инфраструктуру, дублирующую production, но фактически без нагрузки. Конечно, хотелось бы сразу сделать горячий/активный резерв, но для его создания требовались серьёзные изменения как в инфраструктуре, так и со стороны работы приложения. Пойти на это тогда не получалось, потому что нужно было решать проблему отказоустойчивости в относительно короткие сроки. Идею активного резерва мы не забросили, но вернёмся к ней позже.

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

Сказано — сделано. Инфраструктура была продублирована, а между дата-центрами поднят VP LAN с двумя независимыми интернет-каналами. Для MySQL была организована репликация master-slave на старте и доросла до master-master репликации с RO на одном из узлов, а для NFS — синхронизация через lsync. Переключение клиентского трафика между дата-центрами (в случае аварий или по другой необходимости) в первое время производилось вручную, без детально описанного плана.

Аварийный план

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

Почему «с минимальным пониманием»? Всё просто: отказ инфраструктуры происходит в самый неподходящий момент. А ведь в такие моменты последнее, что хочется видеть при возникновении любых проблем, — это приборную панель самолёта с кучей «кнопочек и лампочек», в которых нужно долго разбираться…

Кроме того, чтобы выявить все недостатки/неточности плана и снять страх переключения — ведь речь идёт про нагруженный production, цена ошибки очень высока — был проведён ряд учений совместно с инженерами «ВсехИнструментов». Это был незабываемый месяц ночных посиделок для оттачивания переключений между дата-центрами. Без шуток, этот опыт был наполнен активным общением между инженерами двух компаний, что значительно сблизило наши коллективы, убирая ту самую стену между Dev и Ops, о которой сложены легенды.

В частности, во время этих испытаний всплыл интересный психологический барьер. Даже при наличии хорошего, проверенного плана не каждый инженер был морально готов нажать на красную кнопку (для переключения production-трафика) как можно скорее. Вам знакомо чувство «давайте ещё чуть-чуть подождём — вдруг сейчас всё [т. е. основной ЦОД] само заработает»?.. Чтобы сократить downtime, в план был введён строгий лимит на время простоя, после которого переключение должно выполняться независимо от причин.

Итог этих учений — любая из сторон в случае подозрения (или явных проблем) могла самостоятельно и достаточно оперативно переключить трафик во второй дата-центр.

MySQL

Два дата-центра и… latency — антагонист любой инфраструктуры со множеством ЦОД и резервированием. Здесь нужно искать свой баланс между постоянными затратами на инфраструктуру, скоростью работы приложения и потенциальными рисками бизнеса в случае потери данных. 

По итогам обсуждения возможных рисков пришли к довольно простой с технической точки зрения схеме: репликация типа master-master + для каждого master’а несколько slave-серверов в своём ДЦ, доступных для запросов только на чтение. «Второе плечо» нашей репликации, которое находится на стороне неактивного ЦОД, вообще полностью в read-only, чтобы избежать случайной записи в неактивную реплику:

При такой схеме в случае нештатного переключения, когда полностью пропал доступ к текущему/активному ДЦ, трафик переключается с пониманием, что реплика перестаёт быть консистентной, и части данных может уже не быть в новом активном ДЦ. Это грозит нам необходимостью перезагружать данные во все базы «второго плеча», а коллегам из «ВсехИнструментов» — полуручным режимом восстановления данных, которые не успели синхронизироваться.

Основные  проблемные места при эксплуатации такой схемы: 

  • описанный выше split-brain;

  • длительное восстановление схемы в случае отказа одного из «плеч»;

  • человеческий фактор.

Для иллюстрации последнего достаточно передать привет товарищу, который однажды загрузил INSERT’ы в оба мастера MySQL. Мы не осуждаем этого человека: не ошибается тот, кто ничего не делает. Но после такого инцидента второй мастер стал не просто read-only, а super-read-only, чтобы как можно дальше отодвинуть человеческий фактор.

В процессе развития проекта БД MySQL выросла до 500+ Гб, то есть более, чем в десять раз. Поэтому перезаливка БД таких размеров уже начинает создавать сложности. Хотя как минимум трое человек из нашей команды могут восстановить репликацию, даже если их разбудят посреди ночи, а они будут с завязанными глазами. И вишенкой на этом торте стала простая особенность в репликации, когда MySQL, реплицируя только одну БД приложения, внезапно останавливалась от запроса на изменение пароля пользователя с мастера… И ты, Брут MySQL?

Переключения на резерв. Кто ты, человек или машина? 

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

С помощью API CDN’а удалось автоматизировать переключение upstream’ов (а их много) и снять ощутимую часть ручных действий, отнимающих время у инженера. Благодаря этому удалось сократить downtime из-за человеческого фактора в несколько раз (!).

Однако, к сожалению, в схеме master-master с БД переключение базы осталось в полуручном режиме, так как часть функциональности приложения (cron, consumers) не предполагает работу в двух дата-центрах одновременно. Поэтому всегда нужен человек, принимающий сложное решение: ждём восстановления ЦОДа и оставляем cron’ы на месте или «сжигаем мосты», отключая проблемную инфраструктуру и СУБД, пока она не наделала проблем.

Возвращаясь к теме переключения трафика: зачем ждать инженера, который посмотрит на недоступный сайт и нажмёт заветную кнопку? Оказывается, в 90% случаев мы можем не терять время и на это. Следующий шаг по автоматизации переключения upstream’ов в CDN — простые правила для primary и backup:

  • Если основной upstream лёг — автоматически переключаем трафик на резерв. Но резерв оставляем в состоянии read-only (без части функциональности) — до решения дежурного инженера.

  • Дежурный инженер, видя, что трафик переключился, по сути просто «фиксирует» это переключение и продолжает с другими нужными действиями — по СУБД, cron, consumer — уже в более спокойном ритме.

Звучит странно? Но спросите в отделе продаж, что лучше: полностью недоступный сайт (полная потеря трафика) или «деградация» в его работе (потеря части функций)? Для нас это решение подошло как «меньшее из зол».

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

Kubernetes

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

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

  • разработчикам, силами которых приложения стали микросервисами, соответствующими 12 факторам;

  • роли Kubernetes именно как оркестратора, управляющего жизненным циклом контейнеров (создание, пробы, перезапуск, обновление…);

  • полной автоматизации CI/CD-процессов.

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

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

1. Канареечные выкаты

В статье упоминалась возможность выката в резервный ЦОД для тестирования потенциально опасных релизов. Однако на резерве нет реального пользовательского трафика, а нам очень хотелось бы тестировать новые релизы и на пользователях — точнее, на некоторой их части. На помощь приходит canary deployment, в случае которого процент трафика уходит на новую версию приложения (происходит A/B-тестирование).

Чтобы его реализацией на базе ingress-nginx в Kubernetes было удобно пользоваться (самим разработчикам), в административной панели приложения появились настройки, регулирующие, сколько именно и какой именно трафик уходит на новую версию.

2. Автомасштабирование consumer’ов

Иногда нужно «подкинуть угля» в какие-то функции сервиса, чтобы он смог выдать требуемую производительность в условиях ограниченных ресурсов. Речь о HPA. Понятно, что автомасштабирование идеально ложится на «резиновые» дата-центры вроде AWS/GCE/GKE. Но и в условиях фиксированного количества виртуальных машин HPA может использоваться, если имеется какой-то запас узлов для масштабирования сервисов.

Автоматическое масштабирование consumer’ов происходит в зависимости от нагрузки на них. В нашем случае источник такой метрики — Prometheus + exporter:

  • Exporter собирает как бизнес-метрики приложения, так и просто размеры очередей.

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

HPA позволяет без вмешательства человека автоматически добавлять consumer’ов на внезапно активную очередь и уменьшать их количество, если нагрузка спала. Повторюсь, что это требует некоторый запас по ресурсам.

3. Штатные функции Kubernetes

Kubernetes выступает по сути супервизором для приложений — он следит за их жизненным циклом: перемещение между узлами, liveness/readiness probes, rolling updates, PodDistruptionBudget… Всё это позволяет обеспечивать нужный SLA:

  • В случае отказа узла Pod’ы с приложением переезжают на другой узел.

  • Проверки (probes) позволяют убирать из балансировки «призадумавшееся» приложение и дать ему «отдохнуть» или перезапустить, если оно зависло.

  • Rolling update обеспечивает плавный деплой без простоя.

  • PodDisruptionBudget защищает от автоматического вывода из балансировки критичного количества реплик приложения. Например, у Redis-кластера три узла — хотя бы один всегда должен быть Ready, чтобы можно было сделать evict Pod’ов с узла.

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

4. Штатные функции Deckhouse

В особенности — прозрачный мониторинг/статистика. Kubernetes-платформа Deckhouse из коробки предоставляет преднастроенные Grafana со всевозможными графиками, в том числе по RPS/response_code для отдельных vhost/location/controller:

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

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

Тема затрагивалась в нашем докладе «10 лет on-call. Чему мы научились?», из которого можно узнать подробности о пути алертов в системе.

5. Интеграция запуска тестов в CI

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

  1. 2017-й. Старт проекта. CI — полуручной, тесты — полностью ручные, выполняются на ПК разработчика.

  2. Конец 2017-го. Появилась автоматическая сборка — тогда ещё на dapp (это старое название werf). Pipeline выглядит так: Build → Stage deploy → Production deploy.

  3. Весна 2018-го. Появились:

    1. тест-контур и возможность заливки в него БД с production по кнопке;

    2. деплой во второй ЦОД (production, холодный резерв);

    3. индивидуальные окружения для разработчиков.

  4. Летом и зимой того же года добавлена интеграция с Blackfire и автоматические тесты PHPStan и Selenium.

  5. Весна 2020-го. Добавлены CodeSniffer, юнит-тесты, canary deployments.

  6. Текущее состояние. Ещё больше разных тестов и фич: deptrack-report, phploc, code coverage, GitLab pages (внутренняя документация), acceptance-тесты на canary, sanity-тесты на canary, тесты API.

6. Простое обновление PHP

Обновление с PHP 7.0 до 7.4 происходило безболезненно за счёт тестирования всех компонентов в отдельных изолированных окружениях с возможностью лёгкого отката.
Участие DevOps-инженеров/админов было минимальным и не требовало изменений со стороны инфраструктуры (да, пришлось поправить версии пакетов в werf.yaml). Теперь PHP обновляется полностью силами команды разработки.

Акт третий. Следуем за мечтой

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

Главная амбициозная мечта, которая осуществилась, — мультиЦОД-решение. Оно подразумевает:

  • Не переключение между резервами, а одновременная работа в трёх разных дата-центрах со своими независимыми каналами, резервированием и зданиями.

  • Балансировщик пользовательского трафика, который распределяет пользователей на 3 дата-центра. Для части внутренних сервисов уже работает с внутренним балансировщиком и некоторой магией в виде split DNS.

  • Балансировщик для MySQL. А как же latency?.. Ведь это три разных дата-центра. Решение этой проблемы стало возможно благодаря тесному взаимодействию коллег из «ВсехИнструментов» и из ЦОДов. У нас появилась локальная сеть между тремя независимыми зданиями трёх дата-центров, каждый из которых соединён с остальными выделенной оптикой, благодаря чему была получена отказоустойчивая локальная сеть с минимальным latency. Это было обязательным условием, позволившим нам собрать три одновременно работающих MySQL-инсталляции в кластере (Percona Xtradb Cluster) — уже настоящем, т.е. синхронном, а не реплике мастер-мастер — с балансировкой в виде ProxySQL перед ними. Синхронный кластер — это довольно «капризная» история, выдвигающая серьёзные требования к оборудованию, обеспечивающему его работу. 

  • Балансировщик для memcache, RabbitMQ и внутренних компонентов. Общение внутренних компонентов также происходит через балансировщик, т.е. в случае отказа приложения А в первом ЦОДе из балансировки выводится только приложение А в первом ЦОДе, а приложение Б продолжает ходить в оставшиеся реплики приложения А в двух других ЦОДов. ЦОД не выводится полностью — только отказавший компонент.

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

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

Заключение

Многолетняя кооперация «Фланта» и «ВсехИнструментов» представляется нам отличным примером, как сотрудничество, начавшееся с совершенно стандартного проекта средних размеров, с течением времени вырастает до крупных масштабов, принося понятную пользу обеим сторонам.

За 5 с лишним лет нашей совместной работы «ВсеИнструменты» выросли в 5 раз. В ИТ-департаменте работают 300 сотрудников, 170 из которых — разработчики. Мы с интересом наблюдали за развитием проекта и непосредственно в этом участвовали:

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

  • Приложение эволюционировало от простого монолита до микросервисов, соответствующих 12 факторам, готовых к масштабированию и высоким нагрузкам.

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

Да, в процессе нашего совместного развития бывали ошибки, но правильные выводы из случившегося и предпринятые меры на будущее позволяют уверенно двигаться дальше, — и это замечательно! Завершая статью, хотелось бы от лица всего нашего коллектива поблагодарить коллег из «ВсехИнструментов» за все годы нашего увлекательного сотрудничества.

P.S.

Читайте также в нашем блоге:

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


  1. Adjuster2004
    19.01.2023 21:25

    В начале 2006 год, в конце 2020, а в заголовке статьи 5 лет...

    За 5 лет от нескольких компов до мульти дата центра. ????


    1. shurup
      20.01.2023 07:40
      +4

      2006 год указан в описании самого проекта ВсеИнструменты, это момент основания компании. А далее (в следующем абзаце) написано:

      Когда проект пришёл к нам в 2017 году…


      1. Adjuster2004
        20.01.2023 08:40

        Интересно, сам бизнес в эту пятилетку сильно вырос?

        Судя по описанию, до 2017 года все сервисы успешно работали на "нескольких виртуалках".


        1. shurup
          20.01.2023 08:47
          +2

          Да, сильно вырос. Например, есть такая публичная информация.


          1. Adjuster2004
            20.01.2023 08:52
            +1

            Ок. Принято.

            Только прибыль падает, судя по той же информации.


  1. shornikov
    20.01.2023 08:44

    Верно ли я понял, что 170 программистов и еще 130 айтишников "принадлежащих" ВИ, привлекли еще и стороннюю фирму для "девопса"?


    1. cristoph_kleist
      20.01.2023 09:04
      +1

      Численность 300 чел. на момент близкий к текущему, на начало сотрудничества было заметно меньше. Плюс в этом составе не надо забывать 1 и 2 линию техподдержки, тестировщиков, аналитиков и менеджмент.


      1. shornikov
        20.01.2023 10:52
        +2

        Тестировщики и прочие - это как раз те 130 человек, так ведь?

        Я понимаю, что сейчас так принято, но не понимаю... Может, потому-что работаю в нано-команде, а то и вовсе один.

        Вот смотрите, их было мало, они позвали вас, вы внедрили "штуку" которая упрощает жизнь IT или экономит деньги бизнеса. Но в результате их стало не меньше, а больше.

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

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

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


        1. cristoph_kleist
          20.01.2023 14:04
          +1

          А как насчет новых целей бизнеса? Штат разработки не связан линейно с имеющимися средствами автоматизации. А вот развитие функционала сервисов, внедрение новых типов складов, усложнение логистики и др. автоматизация не заменит. Вы правы, автоматизация "упрощает жизнь IT или экономит деньги бизнеса" - в случае с DevOps, 130 чел. (в числе которых инженеры инфраструктуры) не превратились в условные 300 чел.


          1. shornikov
            20.01.2023 14:36
            +1

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

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

            Вы пишите - развитие функционала сервисов: некий бизнес придумал сервис, там 20 позиций фич. Прикинули - надо 5 программистов. За год написали все 20 фич.
            Работы казалось бы должно быть меньше, - можно парочку сотрудников даже уволить, но штат программистов в этом мире только растет. Почему?

            Дальнейшее развитие продукта ведь не должно идти по экспоненте, основной функционал закладывается изначально.

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


  1. slava_k
    20.01.2023 19:26

    Большое спасибо за статью.

    Какая у "вас"/проекта типизация траффика? Разделение по ФО (РФ) через geoIP, странам, платёжеспособным зонам (на основе анализа пользователей, совершавших покупки за последние Х дней)? Есть ли heatmap таких платёжеспособных зон и если да - то как с ними работаете в плане повышения эффективности расходования ресурсов на такие зоны, также от расходов на рекламу до расходов на логистику в них.

    Проводите ли анализ "сезонности" траффика внутри дня и недели? Возможно, в зависимости от продолжительности резко возросшей нагрузки, имеет смысл заранее запустить резервные мощности в минимально необходимом объёме и за полгода-год сравнить hit rate такого подхода, помогает ли он повысить доступность сервисов или экономить на чём-то.

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

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

    Как у вас реализован мониторинг выполнения SLO? Это скрипты по метрикам из прометея или что-то более сложное? Часто к глобальным метрикам бизнес-инфраструктуры привязывают различные алерты, которые, с учётом ранее оцененной стоимости, могут генерировать различные алерты для различных источников их возможного решения, вплоть до "сопровождения" инцидента в системе глобального мониторинга всего проекта.

    Есть ли у вас версионирование API и список поддерживаемых версий? Если да - как вы с ним живёте и работаете за время развития продукта.
    К примеру, если взять информацию по code coverage и наборы текущих тестов с привязкой к версионности API, то можно сформировать картину по каждому тесту или группе тестов, какие участки кода дольше всего живут и какие отвечают за бОльшее покрытие поддерживаемых версий. В итоге, можно даже попробовать построить стоимость участков такого кода, определить их важность в деньгах/времени и это далее учитывать при оценке сложности/стоимости новых задач для разработчиков, как корректируемый коэффициент предполагаемой стоимости от 1 до 10, либо "не ниже чем". Потенциально, это может существенно помочь в оценке времени и стоимости работ, немного упростить менеджмент задач, к примеру, заранее распределяя заведомо сложные на соответствующих разработчиков.

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

    Всем ли вас устраивает MySQL и если нет - как вы на уровне инфраструктуры и микросервисов проводите подготовку по изоляции проекта от хранилища и переходу на какое-то другое, к примеру, на PostgreSQL? Если, конечно, такая задача вообще имеется на горизонте. Есть ли дробление на типы данных для удобства и ускорения восстановления в случае ЧП, либо это какой-то "монолитный" бэкап, снимающийся с readonly хостов в периоды слабой нагрузки?

    Почему решили продолжать работать с rabbitmq, с учётом уже прилично выросшего масштаба проекта? Всем ли он вас устраивает и нет ли желания переехать на что-то другое, типа kafka/flink/etc?

    Спасибо.