Netflix рассказал о внутренней системе Service Topology, которая почти в реальном времени собирает карту микросервисов для тысяч сервисов и показывает, кто от кого зависит в бою. Для команд, живущих в распределенной архитектуре, это не красивая схема для презентации, а инструмент, который помогает быстрее понять радиус отказа, найти апстрим-проблему и не чинить не тот сервис. Как пишет InfoQ, именно отсутствие такой живой карты чаще всего тормозило разбор инцидентов у инженеров компании.
История началась не с новой моды на графы, а с накопившейся рутины техподдержки разработки. По словам Netflix, за четыре года в инженерных запросах повторялись одни и те же вопросы: какие сервисы завязаны друг на друга, куда долетит сбой после изменения, и локальна ли проблема вообще или это побочный эффект от апстрима. Метрики, логи и трассировки отвечали на части этих вопросов, но не собирались в единое runtime-представление. Для среды, где сервисы выкатываются по нескольку раз в день, статичная схема зависимостей быстро превращается в исторический артефакт. А устаревшая или неполная карта, как отдельно подчеркивает команда, опаснее ее отсутствия: во время инцидента она подталкивает инженеров к ложным выводам.
Service Topology решает задачу через объединение трех источников данных, каждый со своими сильными и слабыми сторонами. Первый слой — сетевые логи потоков на базе eBPF, снятые на уровне ядра. Они дают максимально полное покрытие и видят трафик даже там, где сервисы никак не инструментированы. Минус предсказуемый: из таких данных не вытащишь прикладной контекст, например какой именно API-эндпоинт вызвали. Второй слой — IPC-метрики от инструментированных сервисов. Здесь уже есть уровень протокола, эндпоинтов и прикладной семантики, но только для тех компонентов, которые эти метрики вообще отдают. Третий источник — агрегированные распределенные трассировки, показывающие реальные пути запроса, включая условные ветвления. У трассировок другая проблема: они зависят от sampling и по определению не дают сплошного покрытия. В сумме получается не идеальный источник истины, а три неполных источника, которые закрывают дыры друг друга.
Дальше начинается самое интересное: сырые сетевые потоки сами по себе мало полезны инженеру, который хочет понять прикладную зависимость между двумя сервисами. В логах видно отдельные хопы через балансировщики, NAT-шлюзы и другую инфраструктурную прослойку, но не всегда очевидно, кто с кем действительно взаимодействует на уровне приложения. Поэтому у Netflix трехступенчатый конвейер агрегации, где на втором этапе происходит intermediary resolution — схлопывание многошаговых путей в прямые ребра между сервисами. Это не только делает граф понятным человеку, но и распределяет нагрузку, чтобы не перегревать узкие места там, где через один посредник проходит слишком много трафика. Иными словами, компания не просто рисует стрелочки, а превращает noisy network reality в рабочую модель зависимостей.
С инженерной точки зрения стек у системы вполне соответствует масштабу задачи. Пайплайн обработки работает на Apache Pekko Streams поверх multi-region Kafka consumers. Хранение графа построено на внутренней распределенной key-value системе Netflix, поверх которой добавлен графовый слой для быстрого обхода связей. Доступ наружу отдается через gRPC API с поддержкой многошаговых запросов, фильтров по уровню доступности и бизнес-доменам. Отдельно отмечено жесткое требование по времени ответа: sub-second latency. Для живой карты зависимостей это не косметика. Если запрос к графу занимает вечность, в середине инцидента им просто перестают пользоваться и возвращаются к ручному раскопу логов, а это ровно то, от чего Netflix пытался уйти.
Еще одна практичная деталь — работа с историей. Вместо хранения множества отдельных снепшотов команда использует агрегацию по временным окнам. Это позволяет посмотреть, как выглядела топология в конкретный момент прошлого, не раздувая хранилище до неприличных размеров. Польза тут очень приземленная: можно сопоставить изменение зависимостей с началом инцидента и понять, не возник ли новый маршрут запросов сразу после деплоя, изменения конфигурации или переключения трафика. Для эксплуатации и SRE это, пожалуй, даже важнее самой красивой «живой» картинки. В проде редко ищут абстрактную истину, обычно ищут точку, после которой все поехало.
В более широком контексте кейс Netflix выделяется не громкими словами, а уровнем конкретики. В публичном поле про построение таких систем пишут мало. Большая часть доступных материалов по service dependency mapping заканчивается тем, что можно вытащить из одних только трассировок, например через OpenTelemetry Service Graph Connector. Другие компании используют граф зависимостей как часть более крупной инфраструктурной истории: у одних это контекст для AI-агентов, у других — сопровождение миграции метрик. Но подробный рассказ о том, как собрать многослойный граф в почти реальном времени на масштабе Netflix, встречается редко. Причин тут, похоже, две: либо сама проблема настолько остра у немногих компаний с таким количеством сервисов и объемом трафика, либо решение считается слишком ценным внутренним активом, чтобы раскрывать детали.
Для русскоязычных разработчиков и техлидов из этого кейса есть довольно неприятный, но полезный вывод. Если у вас микросервисов уже столько, что при инциденте первая реакция команды — открыть Miro и спорить, кто кому звонит по сети, значит наблюдаемость у вас неполная, даже если Grafana раскрашена всеми оттенками зеленого. Netflix показывает простую мысль: карта микросервисов должна строиться из нескольких источников сразу, потому что один слой почти всегда врет по-своему. Логи видят не то, трассировки видят не все, метрики понимают только инструментированный мир. Следующий шаг у компании — добавить в граф события деплоя и изменения конфигурации, а в долгосрочной перспективе использовать его как основу для автоматического поиска root cause. Если эта идея приживется не только у гигантов, то через несколько лет вопрос в разборе инцидента будет звучать не «где у нас схема зависимостей», а «почему система до сих пор не подсказала первопричину сама».