Микросервисы: глубокие модули и границы
Вове нравится, что каждую главу этой части Влад начинает с рассказа, как сделать себе больно — микросервисами, событиями, аналитикой, — и только потом показывает, как помогает DDD. Сервис определяется абстрактно: единица с бизнес-логикой и интерфейсом, а система не бывает набором независимых кусков — они всё равно общаются, и от устройства коммуникации зависит вся дальнейшая жизнь. Резать большой сервис по методам — получить распределённый большой ком грязи: локальная сложность падает, глобальная растёт, и вместо парадной двери у каждого дома появляется куча служебных дверей на заднем дворе. Вова вспоминает, как в соседнем подразделении нанятый человек через месяц стал требовать по сервису на метод и переубедить его не удалось — плохие знания о микросервисах могут стоить карьеры. Микросервисы участники называют бизнес-моделью: распределённые автономные команды, частый деплой, тысячи инженеров на разных языках — монолит под это уже не подходит.
Александр разбирает метафору глубоких модулей из книги Джона Оустерхаута, которую заимствует Влад: чем больше сложности спрятано за узким интерфейсом, тем ниже общая сложность системы, а мелкие модули с широкими интерфейсами её увеличивают. На параболе стоимости изменений против гранулярности оба края дороги — монолит и распределённый монолит с паутиной задних дверей, — а микросервисы ищут компромисс в нижней точке. Дальше инструменты DDD как границы: каждый микросервис — ограниченный контекст, но не каждый контекст — микросервис; агрегаты как границы слишком мелки и похожи на деление по функциям, если только агрегаты не общаются постоянно — тогда их держат вместе; поддомены — более безопасный вариант, хотя Вова Иванов видит искушение нарезать их слишком мелко. Александр напоминает, что поддомены не проектируют, а находят, и добавляет к техническим критериям обещания бизнесу: SLA, надёжность, планы развития. Его пример — система, которая отдавала контент для страниц привлечения и одновременно новости для инвестиций: небольшая фича с новостями положила сервис, час недоступности страниц привлечения стоил миллионы рублей, и систему нарезали по важности доменов.
Событийная архитектура без ловушек
Илья вспоминает из книги Форда понятие архитектурного кванта: асинхронное взаимодействие позволяет поставлять части системы независимо. Влад разводит сообщения на события и команды — Вова приводит пример из разбора Клеппмана: пользователь просит логин, занятый отклоняется командой, а свободный порождает событие «пользователь создан». Три типа событий: уведомление с идентификатором и ссылкой за деталями — оно безопаснее, помогает с конкурентностью, потому что за актуальными данными приходят с блокировкой, и облегчает удаление по GDPR; событие с переносом состояния — полный снимок или только изменённые поля, из которых потребитель собирает локальную реплику, почти как CDC, но в форме, которую готовит сам продюсер; и доменное событие — например, флаг смены фамилии одним из супругов, — которое описывает бизнес-факт жизненного цикла объекта и не предназначено для интеграции сервисов: одного такого события для интеграции всегда мало.
Главный пример главы — сервис отчётов, который ждёт по таймеру пять минут, пока сервис оптимизации обработает событие, и только потом идёт за данными; Вова видел такое вживую. Влад раскладывает связанность на функциональную (два сервиса делают одну работу), временную (нужно подождать) и связанность реализации (новый тип события ломает всех). Лечение — открытый хост с публичными событиями, отделёнными от доменных, минимальный интерфейс наружу и уведомление от сервиса оптимизации, по которому отчёты сами забирают готовые данные. Эвристики в конце: надейтесь на худшее — сеть подведёт, сервисы упадут, события придут не по порядку, и потребители должны это переживать. Александр напоминает, что «выживают только параноики» — книга Энди Гроува из Intel о кризисах, когда компания уходила из памяти в процессоры и когда ошибка вычислений в Pentium подняла бунт пользователей, к которому у Intel не было каналов связи. И советы: приватные и публичные события, редкие доменные события наружу, уведомления там, где потребителю нужны строго согласованные данные.
От DWH и data lake к data mesh
Александр открывает главу про аналитику, которую советует всем, кто про это думал: аналитическая модель нужна для инсайтов и предсказаний, транзакционная — чтобы быстро обслуживать запросы пользователей, и хранятся они по-разному. Влад напоминает схемы «звезда» и «снежинка»: таблица фактов и измерения, во втором случае с многоуровневой нормализацией, которая экономит хранение, но платит джойнами. Data warehouse — старый и до поры рабочий подход: ETL-скрипты вытаскивают данные из транзакционных систем, трансформируют на лету и складывают в единую модель предприятия. Проблема в том, что единая непротиворечивая модель на всю компанию не складывается, плодятся витрины, а ETL-скрипты знают кишки сервисов и устаревают с каждой фичей: либо ломаются отчёты, либо замораживается разработка. Александр рассказывает, как у нового продукта сначала нет нормальной отчётности, а потом появившиеся отчёты не дают пилить фичи, не сломав их.
Data lake отказывается от волшебной модели: сырые данные выгружают как есть и трансформируют под задачу, но качество данных плывёт, инкапсуляция сервисов всё равно нарушена, а число скриптов бесконечно; дата-инженеры в отдельном подразделении не знают бизнеса и чинят обвалившиеся отчёты, а DDD-системам, где модель меняется часто, достаётся сильнее всего. Отсюда data mesh — Александр слышал его автора, тогда principal-консультанта ThoughtWorks, на конференции в 2019 году: это DDD для аналитических данных. Четыре принципа: данные организуются вокруг доменов и принадлежат командам ограниченных контекстов, которым нужен свой инженер; данные — продукт первого класса с понятной версионируемой схемой и договорённостями о качестве, то есть опубликованный язык; автономность команд через платформу данных; совместное управление правилами, чтобы автономия не стала анархией. Вова Иванов подтверждает: у них аналитические данные описывают Avro-схемами и публикуют в Kafka. Влад завершает тем, что единый язык, CQRS для множества моделей и паттерны интеграции контекстов применимы и к аналитике. Следующий выпуск — с автором.
Что стоит унести с собой
- 01Микросервисы режут по ограниченным контекстам и поддоменам, а не по методам: глубокие модули с узким интерфейсом снижают общую сложность, а сервис на метод даёт распределённый ком грязи.
- 02Событие-уведомление, событие с переносом состояния и доменное событие решают разные задачи; доменные события — про жизненный цикл объекта, а не про интеграцию сервисов.
- 03Связанность через события бывает функциональной, временной и по реализации; лечат её открытым хостом с публичными событиями и паранойей: сеть подведёт, порядок нарушится.
- 04DWH и data lake ломаются об ETL-скрипты, знающие кишки сервисов; data mesh переносит DDD на аналитику — данные как продукт команды домена с опубликованной схемой.