
Мы в Ситидрайве строим микросервисную архитектуру. Сегодня у нас 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 — зрелый сервис: полная наблюдаемость, проактивный алертинг, профилирование, безопасность данных.
Модель зрелости позволяет оценить любой отдельно взятый сервис по множеству критериев из следующих групп:
Документация — базовая, RFC, Runbook-и;
Тестирование — unit, интеграционные, e2e;
Конфигурация — live-конфигурация, автовалидация конфигов;
Наблюдаемость (логи) — динамический уровень, связка с trace;
Наблюдаемость (метрики) — золотые сигналы, SLI, бизнес-метрики;
Наблюдаемость (алерты) — по техническим и бизнес метрикам, проактивный алертинг;
Наблюдаемость (трассировки) — стандарты, отслеживание ошибочных span-ов
Наблюдаемость (непрерывное профилирование) — локальный профайлинг и рантайм
Верифицируемость — линтеры на код, бд, зависимости;
Работа с БД — тестовые данные, разделение чтения и записи, документация в data hub;
Нефункциональные требования — SLA, HPA, graceful degradation, fallback, chaos-тестирование;
Безопасность — персональные данные, rate-limit, SAST / DAST, доступность извне.
Каждая из этих групп делится на множество критериев, распределённых для разных уровней инженерной зрелости. К сожалению, таблица зрелости слишком большая и мы не можем привести её в рамках статьи, поэтому описали лишь часть критериев.
Таким образом, мы получаем возможность легко проверить какому уровню зрелости соответствует сервис, и что необходимо доработать в рамках тех долга для повышения его уровня.
Команды сами оценивают свои сервисы. После визуализации всё становится очень прозрачно: например, два Тир-1 сервиса могут быть на разных уровнях зрелости — один на Уровень-3, другой на Уровень-1. И сразу видно, куда нужно вкладываться, а где всё более или менее под контролем.
Наша инженерная карта
Тир/Зрелость | Уровень-0 | Уровень-1 | Уровень-2 | Уровень-3 |
Тир-1 | 🚨 Неприемлемо | ⚠️ Риск - Срочно улучшить | ✅ Минимум | 🤩 Отлично |
Тир-2 | ⚠️ Риск | ✅ Хорошо | 🤩 Отлично | 🤩 Отлично |
Тир-3 | ⚠️ Риск | ✅ Хорошо | 🤩 Отлично | 🤯 Избыточно |
Тир-4 | ⚠️ Риск | ✅ Хорошо | 🤯 Избыточно | 🤯 Избыточно |
Эта карта стала базой для планирования квартальных задач, распределения бюджета и подготовки к пиковым нагрузкам. Теперь любой руководитель или SRE может ответить на простой, но критичный вопрос: «Сколько из наших Тир-1 сервисов достигли хотя бы второго уровня зрелости?». Эта информация — золото при планировании техдолга, распределении бюджета и подготовке к пикам нагрузки.
Как это всё внедрялось?
Изначально модель инженерной зрелости существовала как документ. После публикации мы донесли её до руководителей через коммуникации в рабочих каналах и обсуждения на общих созвонах.
Хэды увидели большой объём техдолговых задач, которые теперь стали явными. При этом продуктовые задачи никто не отменял — нужен был баланс. У нас действует правило: около 30% задач квартала должны быть направлены на устранение техдолга. И важно понимать — документ не создавал новый техдолг, он лишь подсветил уже существующий. Раньше его можно было не замечать, теперь он стал видимым.

Каждая команда отвечает за уровень зрелости своих сервисов. Некоторые руководители начали строить собственные фреймворки оценки, а другие пытались держать все параметры в голове. Получилась фрагментация — единых критериев не было. Мы повторно собрали команду, проанализировали их подходы и создали универсальный фреймворк — рабочую структуру в таблицах. Теперь он позволяет оценивать зрелость сервисов по одинаковым метрикам и отслеживать прогресс.
И как в итоге это работает?
Новой системе требуется постоянная поддержка. Эту функцию выполняет архитектурный совет — группа инженеров из тимлидов и хэдов под руководством главного архитектора. Совет принимает критические архитектурные решения и проводит регулярное архитектурное ревью всех сервисов.
Во время таких ревью совет присваивает каждому сервису ��оответствующий Тир, а также проводит пересмотр уровней раз в полгода. Это позволяет поддерживать единую картину критичности и корректировать приоритеты по мере их развития. В результате:
Команды начали сами планировать техдолг, чтобы довести сервисы до нужного уровня зрелости — без давления «сверху».
Появилась прозрачная карта критичности, и бизнес получил понятное объяснение, почему один сервис важнее другого.
Инцидент-менеджеры перестали распыляться, потому что приоритет инцидента теперь напрямую зависит от Тир-сервиса.
На момент выхода статьи модель пока существует в основном как документация. Чтобы она реально работала в ежедневной практике, мы планируем несколько шагов:
Внедрение во внутренний каталог сервисов. Это позволит сразу видеть, какие сервисы завязаны на более высокий Тир, и оценивать зависимости по карте.
Интеграция с CI/CD. Автоматическая проверка и раннее оповещение помогут быстрее реагировать на критические ситуации.
Расширение применения в on-call. Мы хотим использовать модель для снижения MTTA и MTTR, чтобы инцидент-менеджеры быстрее понимали приоритеты и действовали эффективно.
