Микросервисы без иллюзий. Арифметика архитектурного решения

- -
- 100%
- +

Иллюстрация на обложке С использованием ChatGPT
© Сергей Кирницкий, 2026
ISBN 978-5-0071-4407-0
Создано в интеллектуальной издательской системе Ridero
Пролог. Пост о мониторинге
22 марта 2023 года в инженерном блоге Prime Video Tech вышел текст «Scaling up the Prime Video audio/video monitoring service and reducing costs by 90%». Речь в нём шла о том, как в видеосервисе Amazon масштабировали мониторинг звука и видео и сократили его стоимость на 90%. Автор, инженер Prime Video Марцин Кольны, рассказывал о работе одной команды. Это была команда анализа качества видео (Video Quality Analysis): она следила за потоками, которые в этот момент смотрят зрители. Инструмент искал в них заморозки кадра, повреждённые блоки изображения, рассинхронизацию звука и видео. Пока он работает исправно, зритель о нём не знает.
Команда сообщила, что заменила одним процессом распределённые бессерверные (serverless) компоненты, из которых был собран инструмент, и что расходы на инфраструктуру снизились более чем на 90%. Остальное в посте — подробности: задача, решение, результат. Это обычный жанр инженерных блогов, и читают такие тексты коллеги с похожими задачами. Один инструмент, одна команда, одно число.
Широкое обсуждение началось через шесть недель: 3 мая 2023 года о посте написало издание InfoQ. На следующий день, 4 мая, вышли материалы The New Stack и The Stack. The New Stack назвал свою заметку «Return of the Monolith: Amazon Dumps Microservices for Video Monitoring» — «Возвращение монолита: Amazon отказывается от микросервисов для мониторинга видео». Заголовок The Stack сообщал, что сервис Prime Video отказывается от микросервисов и сокращает счёт за облачную инфраструктуру на 90%. Число 90% взято из заголовка поста без изменений.
В тот же день ссылка на сам пост попала на Hacker News и собрала 989 баллов и 507 комментариев. Тогда же свой текст опубликовал Дэвид Хайнемайер Ханссон, создатель Ruby on Rails: «Even Amazon can’t make sense of serverless or microservices» — «Даже Amazon не может разобраться в бессерверных вычислениях и микросервисах». Публикация, полтора месяца стоявшая в инженерном блоге, за два дня перешла в новостные издания, на форумы и в личные блоги.
5 мая 2023 года ответил технический директор Amazon Вернер Фогельс. В своём блоге All Things Distributed он опубликовал текст «Monoliths are not dinosaurs» — «Монолиты — не динозавры». Он возражал представлению о монолите как о пережитке прошлого. Фогельс напомнил, что программу, в отличие от моста, можно перестраивать и после того, как она построена. Архитектуру, писал он, стоит пересматривать непредвзято и всякий раз, когда система вырастает на порядок, а единого стиля для всех задач не существует. В пример он привёл тот же Prime Video: трансляции матчей американского футбола Thursday Night Football работают на распределённой архитектуре.
Свою позицию Фогельс сформулировал так: «Строить программные системы, способные развиваться, — это стратегия, а не религия» (Building evolvable software systems is a strategy, not a religion). За три дня, с 3 по 5 мая, обсуждение прошло путь от заметки в профессиональном издании до блога технического директора всей компании. Поводом был сервис мониторинга одной команды.
Факт, который стоит зафиксировать сразу: пост описывал один инструмент, а не архитектуру Prime Video. Слово «монолит» в тексте действительно встречалось и относилось к инструменту: один из разделов назывался «From distributed microservices to a monolith application» — «От распределённых микросервисов к монолитному приложению». Но в том же посте команда писала, что микросервисы и бессерверные компоненты работают на большом масштабе. Выбор между ними и монолитом, по её словам, нужно делать для каждого случая отдельно.
На одном конце этой истории — пост об инструменте, который ищет заморозки кадра. На другом — заголовок о том, что Amazon отказывается от микросервисов. Оговорка «for Video Monitoring» в заголовке The New Stack сохранилась, но стоит в самом конце, после слов об отказе. Оба текста описывают одно и то же событие.
Уточнение по первоисточнику реакцию не отменяет: она факт сама по себе. У неё есть свои даты, свои числа и свои участники, и задокументирована она не хуже самого поста. Технический текст о внутреннем инструменте не становится мировой новостью, если не попадает в давно назревшее напряжение. Пост его не создал, а обнаружил. В мае 2023 года мы обсуждали микросервисы как таковые.
Объяснения такому отклику в посте нет. Он не сообщал о сети ничего нового и не претендовал на это. Сетевой вызов (network call) был дороже вызова функции (function call) задолго до 2023 года; задержки, потери пакетов и частичные отказы появились не тогда. Отсюда вопрос: почему одно число из одного блога прозвучало как откровение, если физика сети не менялась с 1990-х?
В таких спорах под словом «микросервисы» часто смешиваются две разные вещи. Первая из них — контейнеризация, и она не предмет критики этой книги. Docker решает реальную и давнюю проблему: программа работает на машине разработчика и не работает на сервере, потому что окружение там другое. Контейнер упаковывает приложение вместе с его окружением, и главная причина расхождения между машинами уходит. Монолит в контейнере получает изоляцию, воспроизводимость и простое развёртывание. Контейнер меняет способ поставки программы, а не её устройство: ни одного сетевого вызова внутри неё от упаковки не появляется.
То же относится к соседним технологиям. Kubernetes — оркестратор: он перезапускает упавшие процессы, добавляет копии под нагрузкой и разворачивает новые версии, и единое приложение получает всё это наравне с сотней сервисов. Монолит в Kubernetes остаётся монолитом. Облако — место, где работает система, а не способ её разрезать.
Есть и задачи, распределённые по природе. Сеть доставки содержимого (CDN) держит копии данных ближе к пользователям на разных континентах; мессенджер доставляет сообщения между устройствами в разных концах мира; геораспределённая база хранит данные в нескольких регионах сразу. Распределённость таких систем задана самой задачей, и книга с ней не спорит.
Вторая вещь — архитектурное дробление: разбиение единой бизнес-логики на десятки сервисов, которые общаются по сети. Она и есть предмет книги. Задача, которую можно решить в одном процессе, добровольно превращается в распределённую. Вызов функции заменяется сетевым вызовом, и вместе с ним меняется природа операции. Внутри процесса вызов либо выполнен, либо нет; по сети у него появляется третий исход: ответ не пришёл, и неизвестно, была ли операция выполнена. Место, где произошла такая замена, книга называет сетевой границей, и без уточнений слово «граница» дальше означает только его.
Две эти вещи легко спутать, потому что в массовую практику они пришли почти одновременно. Docker стал открытым проектом в 2013 году, а статья Джеймса Льюиса и Мартина Фаулера «Microservices» («Микросервисы») вышла в 2014-м. Фраза «мы переходим на Docker» незаметно превращалась в «нам нужно 30 сервисов», хотя одно из другого не следует. Каждый шаг на этом пути выглядел разумным для тех, кто его делал. Механизм, которым упаковка обрастала сетевыми границами, — такой же предмет книги, как само дробление.
Различить контейнеризацию и дробление в собственной системе можно без специальных средств. Монолит в Docker — контейнеризация; 30 сервисов с Kafka между ними — распределённая система. В первом случае одна пользовательская операция остаётся цепочкой вызовов функций внутри процесса и может завершиться одной транзакцией базы. Во втором та же операция проходит через несколько сервисов, у каждого своя база, и сообщение в шине становится частью бизнес-логики. Kafka здесь упомянута не в упрёк: шина хорошо делает свою работу. Но её появление внутри единой бизнес-логики означает, что сетевых границ в системе уже много.
У этого различения есть оговорка. Единое приложение, которое ходит в базу данных по сети, уже распределено. Но распределённость в нём сосредоточена на одной границе, между приложением и базой, и эту границу закрывает зрелый транзакционный движок. Дробление размножает такие границы. Поэтому сравнивать системы имеет смысл не по числу контейнеров, а по числу мест, где вызов функции стал сетевым.
У разговора о дроблении три стороны: происхождение нормы, её стоимость и опыт тех, кто её проверил. Происхождение — это история о том, как решение организационной проблемы нескольких компаний стало нормой для всех. У стоимости есть счёт за каждую сетевую границу, строка за строкой: время, согласованность, отказы, инфраструктура, люди. Опыт — свидетельства команд, которые посчитали эту стоимость на собственных системах.
Ни одна из этих сторон не начинается в 2023 году. Заголовки мая сообщали о посте, но не объясняли, почему его прочитали именно так: они сами были частью отклика. Чтобы понять реакцию на пост 2023 года, нужно вернуться на двадцать лет назад, к одному служебному распоряжению в Сиэтле.
Часть I. Как мы сюда попали
История когнитивной ошибки: как решение организационной проблемы нескольких компаний стало техническим стандартом целой индустрии.
Между служебным распоряжением в Сиэтле начала 2000-х и архитектурой стартапа из восьми человек лежит несколько пересказов. Распоряжение решало задачу людей, а не кода. Фредерик Брукс ещё в 1975 году показал, что усилия на попарные согласования в группе из n человек растут как n (n—1) /2. Когда практику описали, в описании было и предупреждение о цене. Рынок взял перечень характеристик, а предупреждение осталось в тексте.
Никто на этом пути не лгал. Каждый честно пересказывал предыдущий шаг, только короче, и на каждом шаге терялись условия, а выводы сохранялись. Команда из восьми человек, выбравшая десятки сервисов, поступала разумно внутри системы стимулов, которая вознаграждала сложность; сумма разумных решений дала результат, которого никто не выбирал. К 2018—2020 годам открытых сомнений стало больше, но спорили на языке вкусов, а не чисел. Идея была верной для своих авторов. Ошибка возникла в переносе.
Глава 1. Проблема, которую решали
В 2006 году Вернер Фогельс, технический директор Amazon, рассказал журналу ACM Queue о главной архитектурной перемене компании за пять лет. Amazon ушёл от двухуровневого монолита к распределённой платформе сервисов и называл это сервис-ориентированной архитектурой. Слова «микросервисы» в том разговоре нет. Практика оказалась старше термина, которым её потом назовут.
Сегодня мы говорим о микросервисах языком технологий: протоколы, контейнеры, оркестрация, развёртывание. Сама практика родилась из другой задачи — не из производительности кода, а из координации людей. То, что позже стало техническим стандартом, начиналось как организационный инструмент: способ дать сотням инженеров работать, не блокируя друг друга. У Amazon первым документом этой истории был не архитектурный проект, а распоряжение о том, как командам работать друг с другом.
Три ранние истории — Amazon, Netflix и Uber — сходятся в этом, хотя мотивы у них разные. Amazon принял управленческое решение сверху. У Netflix организационные причины шли рядом с техническими — надёжностью и масштабом трафика. Uber дробился стихийно, без общего плана, со скоростью собственного найма. Форма мотива разная, предел один: число людей, которым приходится согласовывать изменения друг с другом. Цену дробления ни в одном из трёх случаев не скрывали — её описывали те, кто её платил.
У этого предела простая арифметика: согласований становится больше гораздо быстрее, чем людей. Каждое изменение общей схемы данных, каждое общее развёртывание, каждый спор о том, чья правка сломала сборку, — это разговор со всеми, кого изменение задевает. На каком-то масштабе граница сервиса перестаёт быть только техническим решением и становится границей переговоров. Команды договариваются о контракте один раз, а не о каждом изменении. Такая граница покупает время, которое иначе ушло бы на согласования. Платить за неё приходится всем, кто её провёл, а покупка есть не у каждого.
1.1. Указ Безоса
Имя главного приложения Amazon видели даже покупатели: оно стояло в адресах страниц магазина. Приложение называлось Obidos. Фогельс в том же интервью 2006 года рассказывал, что компания начиналась с одной программы на веб-сервере, которая обращалась к базе данных. Со временем Obidos вобрал всю бизнес-логику, всё отображение и все функции, которыми магазин стал известен, — похожие товары, рекомендации, отзывы. Для молодого магазина такое устройство разумно: одна программа, одно развёртывание, всё в одном месте.
К 2001 году, по словам Фогельса, стало ясно, что приложение, собиравшее страницы сайта, больше не масштабируется. Дело было не только в нагрузке. Баз данных к тому времени было несколько, и все они оставались общим ресурсом, который мешал наращивать бизнес. Фогельс объяснял это прямо: и сайт, и внутренние процессы не могли развиваться свободно, потому что ими пользовалось множество разных команд. Техническое ограничение и организационное здесь совпали: общее было трудно и масштабировать, и менять.
Как это выглядело изнутри, публичные источники описывают скупо. Роб Бригхэм из AWS на конференции re: Invent 2015 года называл сайт Amazon 2001 года большим архитектурным монолитом. В его описании части системы были так тесно связаны, что вели себя как одно целое, и каждое изменение уходило в боевую среду только вместе со всем приложением.
Точного числа инженеров тех лет компания не публиковала. По пересказу доклада Бригхэма в The New Stack (2015), в 2000 году инженерная группа сводила в одну версию изменения сотен разработчиков. Для них общий код и общие базы означали одно: изменение схемы задевало чужую работу и требовало согласования всех со всеми. Сотни людей меняли одно приложение и ждали друг друга.
Распоряжение, с которого началась перестройка, никогда не публиковалось. Его знают по пересказу Стива Йегге, который проработал в Amazon около шести с половиной лет, а к 2011 году — столько же в Google. В октябре 2011 года Йегге написал длинный пост в Google+ для коллег, но ошибся с настройками доступа, и текст стал публичным. Автор его удалил, однако копии уже разошлись. Дату распоряжения Йегге называет сам и с оговоркой: около 2002 года, плюс-минус год.
В его пересказе распоряжение Джеффа Безоса требует следующего. Все команды отныне открывают свои данные и функции только через сервисные интерфейсы и общаются друг с другом только через них. Никакое другое взаимодействие между программами не допускается: ни прямого связывания, ни чтения чужих хранилищ данных, ни общей памяти, ни обходных путей. Технология не важна: HTTP, CORBA, публикация с подпиской или собственный протокол. Любой интерфейс с самого начала проектируется так, чтобы его можно было открыть внешним разработчикам, без исключений; кто этого не сделает, будет уволен.
Сам Йегге вводит этот перечень словами «что-то в таком роде» (something along these lines). Это пересказ по памяти спустя девять лет, а не документ. Есть в нём и заключительное пожелание хорошего дня, но его Йегге тут же признаёт своей шуткой, а не словами Безоса. Проверять исполнение, по его словам, Безос поручил группе во главе с Риком Дальзеллом, директором по информационным технологиям.
В те же годы появилась и вторая мера — команда на две пиццы. Колин Брайар и Билл Карр в книге 2021 года рассказывают о её происхождении так: Безос предложил не управлять зависимостями между командами, а убрать их. Реализацию получил тот же Дальзелл, и он вернулся с моделью, в которой команда не больше, чем можно накормить двумя большими пиццами. Журналист Брэд Стоун в 2013 году называл такие команды автономными группами меньше десяти человек и относил объявление реформы к началу 2002 года.
В распоряжении нет ни слова о том, как писать код внутри команды. Язык, хранилище и протокол команда выбирает сама; пересказ прямо говорит, что технология не важна. Регулируется другое: кто с кем может разговаривать и каким способом. Единственный разрешённый канал между командами — сетевой вызов (network call) через опубликованный интерфейс. Это управленческий документ, написанный языком архитектуры.
Брайар и Карр передают замысел Безоса почти теми же словами: команды должны взаимодействовать через машины и чётко определённые интерфейсы, а не через людей, письма и совещания. Фогельс в 2006 году описывал ту же перемену с другой стороны. Решение он называл итогом серьёзного самоанализа: компания пришла к выводу, что сервисы дадут ей нужную степень изоляции. По его словам, у каждого сервиса есть своя команда, и она полностью за него отвечает, включая эксплуатацию: кто сервис построил, тот и держит его в боевой среде. Граница сервиса совпала с границей команды.
Из этого следует главное для всей истории. Сначала решено, что команды будут отделены друг от друга, и только потом — как они будут обмениваться данными. Если читать распоряжение как архитектурный манифест, в нём видна техника. Если читать его как приказ по организации, видно, ради чего эта техника понадобилась.
За следующие пару лет, по свидетельству Йегге, Amazon изнутри превратился в сервис-ориентированную архитектуру. Масштаб перемены виден по числам Фогельса: в 2006 году приложение, собирая главную страницу Amazon.com, обращалось более чем к ста сервисам. В статье 2007 года о хранилище Dynamo инженеры Amazon писали о более чем 150 сервисах на один запрос страницы и о сотнях сервисов в целом. На месте одного приложения с общими базами стояла сеть сервисов со своими командами.
Цену Йегге описывает подробно. Заявка о сбое теперь могла пройти через цепочку из двадцати сервисов, прежде чем находился её настоящий владелец. Даже при отклике каждой команды за пятнадцать минут на поиск могли уйти часы, если не построить для этого отдельную систему метрик и отчётов. Любая соседняя команда могла случайно завалить чужой сервис запросами, поэтому квоты и ограничение нагрузки понадобились в каждом сервисе. Мониторинг и контроль качества, по его формулировке, превратились в одно и то же: каждый интерфейс приходится проверять постоянно, прямо в работе. Сотни сервисов нельзя найти без отдельного механизма обнаружения, а отлаживать чужой код без единого стандартного способа запускать любой сервис стало почти невозможно.
Ещё один урок Йегге формулирует не технически. Работа через сервисы научила команды не доверять друг другу почти так же, как не доверяют внешним разработчикам. Это не упрёк командам, а свойство устройства: интерфейс, который в любой момент могут открыть чужим, приходится защищать и от своих. Доверие между соседями сменилось проверкой — квотой, контрактом, наблюдением за каждым вызовом.
Карточка масштаба
Компания, год: Amazon, 2001—2007; распоряжение — около 2002 года, по воспоминанию Йегге (плюс-минус год).
Инженеров: точных данных нет; по рассказу Бригхэма (re: Invent 2015) — сотни разработчиков.
Пользователи / трафик: опубликованных данных нет.
Сервисов (до → после): одно приложение Obidos и несколько общих баз данных → более 100 сервисов на одну страницу (2006), более 150 (2007), сотни в целом.
Что именно изменилось: данные и функции команд доступны только через сетевые интерфейсы; прямой доступ к чужим базам запрещён; команда отвечает за свой сервис и его эксплуатацию; команды меньше десяти человек.
Источник: S. Yegge (2011); J. Gray, W. Vogels, ACM Queue (2006); G. DeCandia et al. (2007); R. Brigham, re: Invent (2015), по пересказу The New Stack (2015); B. Stone (2013); C. Bryar, B. Carr (2021).
Насколько можно доверять пересказу, стоит сказать прямо. Формулировкам — нет: это память одного человека с шуткой автора внутри. Структуре — да, потому что её независимо подтверждает Фогельс: прямого доступа к базе снаружи сервиса нет, данных между сервисами никто не делит. С датой хуже: Фогельс называет 2001 год, когда приложение перестало справляться, а Энди Джесси, руководитель AWS, в 2016 году относил превращение Amazon в сервисную компанию примерно к 2000 году. Надёжно известно одно: в начале 2000-х Amazon сознательно перестроился вокруг сервисов, и решение было принято наверху.
Amazon видел цену и платил её. По словам Йегге, который ушёл из Amazon в середине 2005 года, сервисы там стали строить уже не из страха увольнения, а потому что поняли, что так правильно. Альтернативу компания знала по собственному опыту. Против часов, потерянных на поиске владельца сбоя, стояло ожидание, которое каждое изменение в Obidos проводило в общей очереди. Для той организации и того числа людей сделка окупалась.
При этом сама потребность договариваться никуда не делась. Она переехала из общего кода и общих баз в контракты интерфейсов, квоты, дежурства и мониторинг. Amazon обменял постоянное согласование всего со всеми на редкие и жёсткие договорённости на границах команд.
Требование проектировать любой интерфейс так, будто его однажды откроют внешним разработчикам, со временем перестало быть мысленным упражнением. В ноябре 2004 года Amazon открыл бета-версию очереди сообщений SQS. В марте 2006 года вышло хранилище S3, и в объявлении компания писала, что даёт любому разработчику доступ к той же инфраструктуре, на которой работают её собственные сайты. Бета вычислительного сервиса EC2 открылась в августе 2006 года.
Связь распоряжения с AWS держится на свидетельстве одного участника. Йегге в 2011 году писал, что Безос первым понял: инфраструктуру, построенную для продажи и доставки книг и прочих товаров, можно превратить в универсальную вычислительную платформу. Джесси, рассказывая в 2016 году о происхождении AWS, начинал с Merchant.com — проекта около 2000 года, который открывал платформу Amazon другим продавцам. Чтобы запустить проект, систему пришлось разобрать на документированные интерфейсы, и Amazon, по словам Джесси, очень тихо стал сервисной компанией; дальше в рассказе идут трудности с инфраструктурой. О распоряжении Безоса он не говорит, но и его версия выводит AWS из той же дисциплины внутренних интерфейсов.
Термина «микросервисы» у этой истории ещё нет. Amazon не изобретал архитектурный стиль: он решал, кто с кем разговаривает и во что это обходится, и продавать интерфейсы, спроектированные как внешние, начал уже потом. Интерфейсы — побочный продукт разделения людей, а AWS — побочный продукт интерфейсов.
1.2. Netflix после катастрофы
В августе 2008 года у Netflix случилось крупное повреждение базы данных, и три дня компания не могла отправлять подписчикам DVD. Для сервиса, который рассылал диски по почте, это была остановка самой заметной части работы. По сообщениям прессы того времени, сбой пришёлся на 12—14 августа. Причину компания тогда называла лишь технической проблемой, а какая именно система хранения отказала, так и не уточнила. Об инциденте рассказали сами инженеры — Юрий Израилевский, Стеван Влаович и Руслан Мешенберг — в посте «Completing the Netflix Cloud Migration» («Переезд Netflix в облако завершён») в феврале 2016 года. С этого сбоя, по их словам, и начался путь компании в облако.
Вывод из сбоя авторы поста формулируют технически. Компании пришлось уйти от «вертикально масштабируемых единых точек отказа» (vertically scaled single points of failure), таких как реляционные базы в собственном дата-центре. Вертикальное масштабирование означает, что растущую нагрузку берёт на себя всё более мощная машина. Пока такая машина одна, её отказ останавливает всё, что от неё зависит. Замену Netflix искал в горизонтально масштабируемых распределённых системах в облаке, где нагрузку делят много одинаковых машин и потеря одной не видна снаружи. Причина перестройки здесь разумная, техническая и привязанная к конкретному сбою.
Вторая причина — масштаб. По данным того же поста, с 2008 по 2016 год число стриминговых участников выросло в восемь раз, а общий объём просмотра — на три порядка. Годовые отчёты дают близкую картину, хотя считают по-разному: около 9,4 млн подписчиков на конец 2008 года вместе с дисками и 74,76 млн участников одного только стримингового сервиса на конец 2015 года. Само видео шло к зрителям не из облака, а через собственную сеть доставки Netflix — Open Connect. Из этого следует, что рост просмотра в тысячу раз ещё не означает такого же роста нагрузки на серверы. Авторы поста пишут, что с новыми ресурсоёмкими функциями и растущими объёмами данных поддержать такой рост из собственных дата-центров было бы крайне трудно: серверы просто не успевали бы ставить в стойки.



