Мы в Ситидрайве строим микросервисную архитектуру. Сегодня у нас 200+ сервисов, за которыми стоят свыше 20 автономных команд — всего больше 150 инженеров. Казалось бы, идеальная модель: каждая команда быстро выкатывает свои фичи без лишней бюрократии. Но была и обратная сторона — нет единого понимания, какие сервисы действительно критичны, как они связаны друг с другом и куда развивать систему дальше.

Но нам удалось с этим справиться — мы привели сотни микросервисов в порядок и сделали систему предсказуемой. В этой статье я расскажу про путь команды к внедрению тир-листа, модели зрелости, управлению зависимостями и приоритетами инцидентов.

Что пошло не так в системе из 200+ сервисов

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

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

И тут мы задумались ввести Тир-лист

Тир-лист — это не про «важные» и «неважные» сервисы. Это про единый язык, чтобы инженер и бизнес одинаково понимали, какой сервис критичен, а какой нет. Без этой договорённости спорить про SLA, приоритеты и инциденты бессмысленно — каждый видит картину по-своему.

Мы решили разделить все сервисы на четыре уровня:

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

  • Тир-2 — важные. Падение ухудшает UX, ломает часть функционала, но не кладёт весь продукт.

  • Тир-3 — вспомогательные. Поддержка, аналитика — если упадут, клиенты напрямую не страдают.

  • Тир-4 — внутренние и R&D-сервисы, эксперименталки.

А дальше всё строится вокруг тира: SLA, приоритеты инцидентов, допустимые зависимости, требования к зрелости, on-call и даже глубина мониторинга.

Номер тира напрямую определяет приоритет инцидентов: чем ниже номер — тем выше важность для бизнеса, и тем быстрее нужно реагировать. Так, минорная или средняя проблема Тир-1 или Тир-2 важнее, чем критическая проблема Тир-4. Тир задаёт процесс on-call:

  • Тир-1 — 24/7, MTTA ≤ 5 минут

  • Тир-2 — 24/7, MTTA ≤ 15 минут

  • Тир-3 — рабочие часы + on-call, MTTA ≤ 60 минут

  • Тир-4 — Best effort, MTTA ≤ 72 часа

Почему Тир-1 не должен зависеть от Тир-3

Однажды наш Тир-1 сервис упал из-за вспомогательного Тир-3. Мы думали «он же всегда отвечает». С тех пор мы перестали верить в «всегда». 

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

Почему это происходит? 

  • Во-первых, когда Тир-1 сервис зависит напрямую от нижестоящего Тир-2 или Тир-3 без fallback-механики, любой сбой «ниже» моментально тянет за собой падение критического  сервиса. 

  • Во-вторых, многие зависимости не имеют SLA — никто толком не знает, на что реально можно рассчитывать. 

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

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

Матрица зависимостей Тир -> Тир

Тир-1

Тир-2

Тир-3

Тир-4

Тир-1

H / S

S

S

X

Тир-2

H / S

H / S

S

X

Тир-3

H / S

H / S

H / S

X

Tier-4

H / S

H / S

H / S

H / S

H — Hard-зависимость, S — Soft-зависимость, X — запрещено

Hard-зависимости (H) допустимы только между сервисами одного уровня Тир или когда зависимость направлена вверх по Тир, в противном случае такая зависимость должна быть мягкой (Soft) и сопровождаться fallback, чтобы основной сервис продолжал работать даже при падении нижестоящего, например:

  • Тир-3 -> Тир-1: допустимо. Если Тир-1 падает, Тир-3 может аварийно завершиться. Приоритет на восстановление Тир-1.

  • Тир-1 -> Тир-3: только Soft. Если Тир-3 упал, Тир-1 должен продолжить свою работу либо с усечённым функционалом, либо с fallback.

Как мы это применяем:

  • Явные зависимости. Каждый сервис описан в Backstage Manifest. Так, мы легко видим, какие Тир-1 сервисы зависят от нижестоящих.

  • Аварийные учения на продакшн окружении. Намеренно роняем Тир-3 сервисы, чтобы убедиться, что Тир-1 выживают. 

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

Подход

Пример

Кэширование

Тир-1 хранит данные в кэше, обновляет раз в N минут

Message broker

Вместо синхронных запросов — асинхронная отправка

Degraded mode

При сбое Тир-3 отключается часть функционала, но не весь сервис. Либо работает fallback — переключаемся на другой функционал.

Так Тир превратился из абстрактной классификации в рабочий инструмент для управления инцидентами и приоритетами. On-call стал спокойнее и предсказуемее.

Дополнительно оцениваем зрелость сервисов

Но одного Тир-листа оказалось мало. Он показал важность сервисов, но ничего не говорил о том, в каком они состоянии. Поэтому мы ввели вторую ось — модель зрелости сервисов, чтобы отделить «критичность по бизнесу» от «качества инженерной реализации». Тир говорит, насколько сервис важен. Зрелость — насколько он надёжен, предсказуем и поддерживаем.

Мы ввели простую шкалу зрелости, чтобы перестать гадать, где у нас дыры, а где всё ок:

  • Уровень-0 — «как есть». Процессов нет, документации нет, мониторинг коробочный.

  • Уровень-1 — базовый порядок: тесты, документация, метрики, минимальные стандарты.

  • Уровень-2 — надёжность: бизнес-метрики, внятные алерты, готовность к нагрузке.

  • Уровень-3 — зрелый сервис: полная наблюдаемость, проактивный алертинг, профилирование, безопасность данных.

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

  1. Документация — базовая, RFC, Runbook-и;

  2. Тестирование — unit, интеграционные, e2e;

  3. Конфигурация — live-конфигурация,  автовалидация конфигов;

  4. Наблюдаемость (логи) — динамический уровень, связка с trace;

  5. Наблюдаемость (метрики) — золотые сигналы, SLI, бизнес-метрики;

  6. Наблюдаемость (алерты) — по техническим и бизнес метрикам, проактивный алертинг;

  7. Наблюдаемость (трассировки) — стандарты, отслеживание ошибочных span-ов

  8. Наблюдаемость (непрерывное профилирование) — локальный профайлинг и рантайм

  9. Верифицируемость — линтеры на код, бд, зависимости;

  10. Работа с БД — тестовые данные, разделение чтения и записи, документация в data hub;

  11. Нефункциональные требования — SLA, HPA, graceful degradation, fallback, chaos-тестирование;

  12. Безопасность — персональные данные, rate-limit, SAST / DAST, доступность извне.

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

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

Команды сами оценивают свои сервисы. После визуализации всё становится очень прозрачно: например, два Тир-1 сервиса могут быть на разных уровнях зрелости — один на Уровень-3, другой на Уровень-1. И сразу видно, куда нужно вкладываться, а где всё более или менее под контролем.

Наша инженерная карта 

Тир/Зрелость

Уровень-0

Уровень-1

Уровень-2

Уровень-3

Тир-1

? Неприемлемо

⚠️ Риск - Срочно улучшить

✅ Минимум

? Отлично

Тир-2

⚠️ Риск

✅ Хорошо

? Отлично

? Отлично

Тир-3

⚠️ Риск

✅ Хорошо

? Отлично

? Избыточно

Тир-4

⚠️ Риск

✅ Хорошо

? Избыточно

? Избыточно

Эта карта стала базой для планирования квартальных задач, распределения бюджета и подготовки к пиковым нагрузкам. Теперь любой руководитель или SRE может ответить на простой, но критичный вопрос: «Сколько из наших Тир-1 сервисов достигли хотя бы второго уровня зрелости?». Эта информация — золото при планировании техдолга, распределении бюджета и подготовке к пикам нагрузки.

Как это всё внедрялось?

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

Хэды увидели большой объём техдолговых задач, которые теперь стали явными. При этом продуктовые задачи никто не отменял — нужен был баланс. У нас действует правило: около 30% задач квартала должны быть направлены на устранение техдолга. И важно понимать — документ не создавал новый техдолг, он лишь подсветил уже существующий. Раньше его можно было не замечать, теперь он стал видимым.

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

И как в итоге это работает?

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

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

  • Команды начали сами планировать техдолг, чтобы довести сервисы до нужного уровня зрелости — без давления «сверху».

  • Появилась прозрачная карта критичности, и бизнес получил понятное объяснение, почему один сервис важнее другого.

  • Инцидент-менеджеры перестали распыляться, потому что приоритет инцидента теперь напрямую зависит от Тир-сервиса.

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

  • Внедрение во внутренний каталог сервисов. Это позволит сразу видеть, какие сервисы завязаны на более высокий Тир, и оценивать зависимости по карте.

  • Интеграция с CI/CD. Автоматическая проверка и раннее оповещение помогут быстрее реагировать на критические ситуации.

  • Расширение применения в on-call. Мы хотим использовать модель для снижения MTTA и MTTR, чтобы инцидент-менеджеры быстрее понимали приоритеты и действовали эффективно.

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


  1. Dhwtj
    10.12.2025 12:16

    Здорово. Но хотелось бы примеры.

    Потому что у меня всё тир1 (падение неприемлемо, стоимость out of service 100500 в наносек). А всякие там почтовые сервисы или ночные обновления снапшотов для аналитики обсуждать нечего.


    1. Igaritta Автор
      10.12.2025 12:16

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

      Tier-2 это важный функционал, но не являющийся основным юзерфлоу. К примеру это списание денег с карты или радар.

      При таком подходе становится понятно, что разные сервисы объединяют одну критическую функциональность, эти сервисы получают Tier-1 лейбл, к нему уже выставляются инженерные требования

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



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


  1. Dhwtj
    10.12.2025 12:16

    Что-то такое? Ну, чтобы предметно обсуждать

    Прости, Господи, за нейрогенерацию!
    Прости, Господи, за нейрогенерацию!


    1. Igaritta Автор
      10.12.2025 12:16

      Уфф.. Наподобие, но у нас не обязательно сервисы друг с другом только через bus общаются. Можно сходить по grpc, если сервис того же tier или tier - N. Даже можно сходить по grpc в tier + N, но сервис должен ожидать, что tier + N может не ответить и это не должно поломать работу текущего сервиса

      Кстати биллинг на этой схеме должен быть Tier-1 сервис, поездку необходимо рассчитать, необходимо дать клиенту оффер. Но именно списать за нее деньги спокойно может быть tier-2, главное, чтобы биллинг не забыл, что поездка не оплачена и допнул списание

      Tier это именно система лейблов сервисов, она сквозная, лейбл накладывается не на домен, а на сервис


      1. Dhwtj
        10.12.2025 12:16

        Ну так...

        Хотя, прошлая была нагляднее

        CQRS
        CQRS

        Tier это именно система лейблов сервисов, она сквозная, лейбл накладывается не на домен, а на сервис

        А смысл? Смысла мало.

        Проблема: если Tier — просто лейбл на любом сервисе, то:

        - Нет структурной границы

        - Правила только на CI/policy, легко нарушить

        - На схеме не видно архитектуры, только метаданные

        Даже можно сходить по grpc в tier + N, но сервис должен ожидать, что tier + N может не ответить и это не должно поломать работу текущего сервиса

        Тогда это просто требования к синхронности / асинхроннонности, без каких-то схем зависимостей?


        1. Igaritta Автор
          10.12.2025 12:16

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

          Тиры - лейблы для сервисов, показывающие важность для бизнеса. Они выставляют границы уровней зрелости (в статье таблица приведена)

          Уровни зрелости в себе содержат набор правил, выдвигаемых к сервису.

          За соответствием сервисов к уровню зрелости присвоенного сервису тира следит команда во главе с лидом и архитектурный совет


        1. Igaritta Автор
          10.12.2025 12:16

          Тир-лист не отменяет текущих архитектурных практик, принятых в компании. Он направлен больше на повышение стабильности системы и предсказуемость отказов, снижение вероятности каскадных сбоев


    1. Igaritta Автор
      10.12.2025 12:16

      Так же добавлю, что API Gateway в Ситидрайве тоже Tier-1 сервис, на уровне с другими критическими сервисами, без него клиенты не смогут выполнить основной юзерфлоу


  1. Dhwtj
    10.12.2025 12:16

    1. Какую проблему решали с разделением на микросервисы? Деплой мешал другим командам? масштабирование? или согласование требований? Или строили в соответствии с структурой бизнес юнитов?

    2. Что получили в минус? Сколько инцидентов из-за сети/согласованности до и после? И что в плюс

    3. Сколько людей на платформу? Если >30% инженеров на инфру, а бизнес-фич мало это плохой сигнал.


    1. Igaritta Автор
      10.12.2025 12:16

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