Справочник архитектурных паттернов ИТ-систем
Вы абсолютно правы. Моя доработка выкинула важные элементы: таблицы "Проблема → Решение" для монолита, диаграммы Mermaid и таксономию из 80+ паттернов. Сейчас я восстановлю полную структуру, сохранив новый формат (описание + когда применять + когда не применять), но вернув:
- Все Mermaid-диаграммы.
- Таблицы "Проблема → Решение" там, где они были.
- Полную таксономию (все разделы с 4 по 23).
Ниже — полностью восстановленный и доработанный справочник.
(объединённая таксономия с примерами и Mermaid-диаграммами)
Введение
Архитектурные паттерны — проверенные решения типовых проблем проектирования. Документ объединяет информацию из :
- Конспектов по System Design,
- Материалов VK Cloud и microservices.io (Крис Ричардсон) — классические паттерны микросервисов,
- Книга Брендана Бернса «Паттерны проектирования распределённых систем» — одноузловые, обслуживающие, пакетные и координационные паттерны,
- Современные AI‑архитектуры (Agentic Loop, RAG).
Все диаграммы выполнены в Mermaid.
1. Фундаментальные архитектурные подходы
1.1 Монолитная архитектура
Описание: Монолит — приложение, которое собирается, тестируется и развёртывается как единый артефакт (JAR, WAR, бинарник). Все компоненты — UI, бизнес-логика, работа с БД — выполняются в одном процессе. Масштабирование: вертикальное (scale up) или запуск нескольких копий за балансировщиком.
Ключевая идея: Простота на старте важнее гибкости в будущем. Монолит позволяет быстро итерировать фичи одной командой.
Когда применять:
- Стартап или MVP (первые 6–12 месяцев).
- Команда до 10 разработчиков.
- Требования к uptime не выше 99.9%.
- Бизнес-логика не имеет чётких естественных границ.
Когда не применять:
- Команда > 20 человек.
- Разные модули требуют разного масштабирования.
- Нужно zero-downtime обновление отдельных компонентов.
Проблемы и решения монолита:
| Проблема | Решение |
|---|---|
| Разрастание кода, потеря управляемости | Модульный монолит (логические границы через DDD) |
| Конфликты мержа между командами | Feature-флаги, модули с явными API, contract testing |
| Горячий модуль требует больше ресурсов | Сателлитная архитектура (выделение модуля в отдельный сервис) |
| Медленные сборки и тесты | Инкрементальная сборка, build cache, модульные тесты |
| Невозможность обновить часть системы без downtime | Blue-Green деплой всего монолита |
1.2 Модульный монолит
Описание: Эволюция монолита: код разделён на слабо связанные модули по DDD (bounded contexts). Модули общаются через интерфейсы внутри процесса. Сохраняется единый деплой и, как правило, общая БД с логическим разделением таблиц. Это «лучший мир»: модули изолированы для разработчиков, но физически в одном процессе.
Ключевая идея: Получить выгоды микросервисов (слабая связанность, независимые команды) без их инфраструктурной сложности.
Когда применять:
- Простой монолит вырос до 100+ файлов и теряет управляемость.
- Есть чёткие business capabilities, но инфраструктура не готова к микросервисам.
- Нужны атомарные ACID-транзакции через несколько модулей.
- Команды готовы соблюдать контракты, но не хотят DevOps на каждый сервис.
Когда не применять:
- Модулям нужны разные технологии (Python vs Go).
- Разные модули должны масштабироваться в десятки раз по-разному.
- Сбой в одном модуле физически валит весь процесс.
1.3 Микросервисная архитектура
Описание: Архитектурный стиль, где приложение строится как набор слабо связанных сервисов, каждый под свою бизнес-способность. Каждый сервис владеет своей БД, развёртывается независимо. Общение через синхронные протоколы (REST/gRPC) или асинхронные сообщения (Kafka). Команды могут использовать разные технологии.
Ключевая идея: Независимая доставка ценности разными командами. Один сервис — одна команда.
Когда применять:
- Организация выросла до 3+ команд, которые не хотят ждать друг друга.
- Разные части системы имеют разные требования к масштабированию, времени отклика, надёжности.
- Есть инвестиции в инфраструктуру: service discovery, distributed tracing, централизованное логирование.
- Нужна изоляция отказов.
Когда не применять:
- Меньше 15–20 разработчиков (оверхед превысит пользу).
- Нет зрелых DevOps и CI/CD.
- Бизнес-логика укладывается в 3–5 таблиц.
- Нужна сильная согласованность в реальном времени.
2. Паттерны декомпозиции
| Паттерн | Суть |
|---|---|
| Decompose by Business Capability | По бизнес-способностям (заказы, биллинг, доставка) |
| Decompose by Subdomain | DDD-субдомены (core, supporting, generic) |
| Self-Contained Service | Минимум синхронных вызовов; самодостаточный сервис |
| Service per Team | Организационная граница = граница сервиса |
2.1 Decompose by Business Capability
Описание: Разбиение на основе бизнес-способностей — того, что бизнес делает для получения ценности. Границы подсказывает анализ бизнес-процессов и организационная структура (Conway's Law). Это самый интуитивный способ начать декомпозицию.
Ключевая идея: Структура кода должна зеркалировать структуру бизнеса. Как организованы отделы, так должны быть и сервисы.
Когда применять: Бизнес-способности легко идентифицируются, имеют собственные данные и соответствуют отделам.
Когда не применять: Способности сильно пересекаются по данным или отделы меняются быстрее архитектуры.
2.2 Decompose by Subdomain (DDD)
Описание: Более детальный подход на основе DDD. Выделяются типы субдоменов: core (ключевая компетенция), supporting (поддерживающий), generic (универсальный). Core часто пишут сами, generic — покупают. Границы — bounded contexts с чёткими моделями данных.
Ключевая идея: Защита core домена — самого ценного для бизнеса. Остальное может быть простым или купленным.
Когда применять: Есть чёткое понимание конкурентного преимущества, используется Event Storming.
Когда не применять: Бизнес-логика тривиальна (CRUD) или нет domain expert'а.
3. Одноузловые паттерны (Single‑Node Patterns)
Эти паттерны реализуются на уровне пода/контейнера и добавляют функциональность без изменения кода основного приложения.
3.1 Sidecar
Описание: Вспомогательный контейнер в том же поде, что и основное приложение. Разделяет жизненный цикл, сеть и файловую систему. Добавляет HTTPS, метрики, конфигурацию, circuit breaker — без модификации кода. Приложение не знает о sidecar: читает файлы или слушает localhost.
Ключевая идея: Инфраструктурные сквозные функции (cross-cutting concerns) выносятся в отдельный процесс, не загрязняя бизнес-логику.
Когда применять:
- Legacy-приложение не поддерживает HTTPS, метрики или структурированные логи.
- Нужна динамическая конфигурация без перезапуска.
- Внедряется service mesh (Istio) — каждый pod получает sidecar-прокси.
- Приложение не умеет собирать метрики в Prometheus, а переписывать код дорого.
Когда не применять:
- Код легко изменить (дешевле добавить библиотеку).
- Жёсткие требования к задержкам (sidecar добавляет микросекунды).
- Операционная команда не готова управлять дополнительными контейнерами.
3.2 Ambassador (посол)
Описание: Прокси между клиентом и сервисом. Клиент подключается к Ambassador, который направляет запрос к нужному экземпляру шардированного сервиса, добавляет rate limiting, ретраи, circuit breaking, SSL-терминацию или канареечные развёртывания. Клиент не знает о сложности. Ambassador часто реализуется как sidecar, но может быть отдельным сервисом (Envoy, NGINX, HAProxy).
Ключевая идея: Скрыть сложность маршрутизации, балансировки и экспериментов от клиентского кода.
Когда применять:
- Шардированный сервис (Redis Cluster) — не хотим, чтобы каждый клиент знал алгоритм хеширования.
- Канареечные развёртывания — 10% трафика на новую версию, без изменения кода клиентов.
- Клиент — legacy-код, а нужен rate limiting.
- Быстрая SSL-терминация для группы сервисов.
Когда не применять:
- Клиенты уже реализовали сложную логику ретраев и выбора шарда (переход дороже).
- Каждый запрос критичен к задержкам (дополнительный hop).
3.3 Adapter (стандартизирующий адаптер)
Описание: Приводит разнородные интерфейсы приложения к единому стандарту для внешних систем — мониторинга, логирования, health checks. Например, приложение пишет логи в свободном формате в stdout, а Adapter-контейнер (fluentd, vector) преобразует их в структурированный JSON для ELK. Или health check приложения — нестандартный эндпоинт, Adapter превращает его в /health для Kubernetes.
Ключевая идея: Не меняйте legacy-приложение — адаптируйте его вывод к современным стандартам снаружи.
Когда применять:
- Приложение пишет логи в устаревшем формате (не JSON), а вы внедряете ELK/Loki.
- Метрики приложения не совместимы с Prometheus.
- Health-эндпоинт приложения не соответствует стандартам Kubernetes (не
/healthили не возвращает правильные коды). - Вы не можете или не хотите переписывать код.
Когда не применять:
- Вы контролируете код и можете добавить поддержку стандартов напрямую (дешевле).
- Требуется low-latency: адаптация на уровне контейнера добавляет накладные расходы.
4. Паттерны обслуживающих систем (Serving Patterns)
Формализованные схемы построения сервисов, которые принимают запросы от пользователей.
4.1 Replicated Load‑Balanced Service
Описание: Сервис без состояния (stateless), запущенный в нескольких идентичных репликах. Перед ними — балансировщик нагрузки (L4/L7), который распределяет запросы. Каждая реплика имеет health check endpoint (/health/ready), и балансировщик не направляет трафик на неподготовленные реплики. Не хранит состояние сессии — любая реплика может обработать любой запрос. Если нужно sticky session — используется IP hash или cookie.
Ключевая идея: Простейший способ горизонтального масштабирования stateless сервисов.
Когда применять:
- Сервис не хранит состояние (или хранит в отдельной БД/кэше).
- Трафик растёт, и нужно просто добавить больше экземпляров.
- Нужна высокая доступность: отказ одной реплики не влияет на общую работу.
- Балансировщик уже есть (K8s Service, NGINX, ALB).
Когда не применять:
- Сервис stateful (хранит данные локально).
- Требуется сложная маршрутизация (шардирование, гео-маршрутизация).
- Клиентам нужны sticky session, а балансировщик не поддерживает cookie-based affinity.
4.2 Sharded Service
Описание: Каждый экземпляр сервиса отвечает только за свою часть ключей (шард). Клиент или Ambassador вычисляет хеш от ключа запроса (например, hash(user_id) % N) и направляет запрос в соответствующий шард. Шарды не пересекаются по данным. Добавление нового шарда требует перераспределения ключей (rebalancing). Применяется в распределённых кэшах (memcached, Redis Cluster) и базах данных с шардированием на уровне приложения.
Ключевая идея: Масштабирование через разделение данных по горизонтали, когда одна реплика не может вместить все данные.
Когда применять:
- Объём данных не помещается на одной машине (TB+).
- Запросы к данным можно предсказуемо направить по ключу (user_id, product_id).
- Вы готовы к сложности перешардирования при добавлении узлов.
- Кэш или БД не поддерживает автоматическое шардирование (или вы хотите контролировать его сами).
Когда не применять:
- Объём данных мал (влезает на одну машину).
- Нет естественного ключа шардирования (запросы идут по разным атрибутам).
- Вам нужны сложные JOIN-запросы между шардами (очень больно).
4.3 Scatter/Gather
Описание: Клиентский запрос параллельно отправляется нескольким репликам или шардам. Каждый узел обрабатывает свою часть (поиск в своём индексе, агрегация своих данных). Затем агрегатор собирает результаты, возможно, сортирует, обрезает и возвращает единый ответ. Требуется, чтобы каждый узел умел возвращать частичный результат. Классический пример: поисковые системы (Elasticsearch) и распределённые MapReduce.
Ключевая идея: Параллельная обработка для снижения latency при работе с большим количеством данных.
Когда применять:
- Поисковые системы (Elasticsearch, Solr) — запрос идёт ко всем шардам индекса.
- Распределённые вычисления, где задача естественно делится на независимые подзадачи.
- Системы рекомендаций, где каждый узел возвращает кандидатов, а агрегатор ранжирует.
Когда не применять:
- Запрос требует атомарной транзакции (scatter/gather не гарантирует консистентность).
- Количество шардов очень велико (сотни) — накладные расходы на параллельные вызовы высоки.
- Один из шардов может отвечать очень долго (медленный узел тормозит весь запрос).
4.4 Кэширующая прослойка (Cache Proxy)
Описание: Выделенный прокси-сервер (или библиотека) перед сервисом, который реализует стратегии кэширования: Read-Through, Write-Through, Write-Back, Cache-Aside. При Read-Through прокси при промахе сам идёт в бэкенд, заполняет кэш и возвращает данные. При Write-Through — запись одновременно идёт в кэш и в бэкенд. Прокси скрывает логику кэширования от клиента.
Ключевая идея: Улучшение производительности чтения без изменения клиентского кода.
Когда применять:
- Бэкенд-сервис медленный (БД, внешнее API), а данные имеют высокую частоту чтения и низкую частоту записи.
- Клиентов много, и вы не хотите, чтобы каждый реализовывал Cache-Aside.
- Нужна единая политика кэширования (TTL, eviction) для всех клиентов.
- Вы внедряете CDN-подобное поведение на уровне сервиса.
Когда не применять:
- Данные обновляются очень часто — кэш будет постоянно инвалидироваться.
- Требуется сильная консистенция (read-your-writes).
- Бэкенд уже достаточно быстр (latency < 10 мс).
5. Паттерны координации и выбора владельца (Leader Election)
Когда только один экземпляр сервиса должен выполнять фоновую работу, координировать шаги саги или удерживать блокировку.
5.1 Leader Election (выбор лидера)
Описание: Механизм, при котором из группы идентичных узлов выбирается один лидер, а остальные становятся последователями (followers). Лидер выполняет эксклюзивную работу (например, координацию саги, обработку очереди заданий). При отказе лидера фолловеры запускают новый раунд выборов. Реализуется через распределённые консенсус-алгоритмы (Raft в etcd, ZooKeeper atomic ephemeral nodes) или через аренды (lease) в Consul/etcd.
Ключевая идея: Гарантировать, что критический участок кода выполняется только одним узлом в распределённой системе.
Когда применять:
- Фоновая задача должна выполняться только одним экземпляром (чистка старых данных, агрегация метрик).
- Координация распределённой саги (orchestrator должен быть один).
- Управление заданием из очереди без дублирования (leader получает задания, распределяет между workers).
- Обновление shared-ресурса, который не поддерживает конкурентную запись.
Когда не применять:
- Есть более простое решение — распределённая блокировка на короткое время.
- Все узлы могут делать работу независимо (без состояния).
- Вы не готовы к сложности координации (блокировки, таймауты, split-brain).
5.2 Блокировки (Locks) и аренда (Leases)
Описание: Распределённая блокировка гарантирует, что только один узел входит в критическую секцию (аналог mutex в одной машине, но на кластере). Аренда (lease) — это блокировка с таймаутом: узел получает эксклюзивное право на ресурс на ограниченное время и должен периодически продлевать аренду. При падении узла аренда истекает, и ресурс освобождается. Реализации: Redis SETNX с TTL, etcd lock, ZooKeeper ephemeral узлы.
Ключевая идея: Эксклюзивный доступ к ресурсу в распределённой системе с автоматическим освобождением при отказе.
Когда применять:
- Обработка задания из очереди exactly-once (заблокировал задание → обработал → удалил).
- Выделение уникальных идентификаторов или номеров (инкремент под блокировкой).
- Обновление общей конфигурации (не более одного писателя).
- Координация миграций схемы БД на кластере.
Когда не применять:
- Высокочастотные операции (блокировка добавляет RPC-вызов → латентность).
- Можно использовать оптимистичную блокировку (версионирование в БД) — дешевле.
- Ресурс уже поддерживает идемпотентность — блокировка избыточна.
6. Паттерны коммуникации (межсервисное взаимодействие)
6.1 Внешнее API: Gateway и BFF
Описание: API Gateway — единая точка входа для всех клиентов. Выполняет маршрутизацию запросов к внутренним сервисам, агрегацию ответов от нескольких сервисов, аутентификацию, rate limiting, логирование, CORS. Backend for Frontend (BFF) — специализированный gateway для каждого типа клиента (Web, Mobile, IoT). BFF может возвращать данные в формате, оптимальном для конкретного клиента (например, для мобильного приложения — сжатые, с пагинацией, без лишних полей).
Ключевая идея: Отделить внешний API от внутренней архитектуры, защитить бэкенды и оптимизировать под клиента.
Когда применять (API Gateway):
- У вас несколько бэкенд-сервисов и множество клиентов.
- Нужна централизованная аутентификация и SSL-терминация.
- Хотите агрегировать вызовы к нескольким сервисам в один ответ.
- Требуется rate limiting и защита от DDoS.
Когда применять (BFF):
- Web и Mobile клиенты имеют разные потребности: мобильному нужны сжатые данные и экономия трафика, Web — полные данные.
- Один клиент требует синхронных вызовов, другой асинхронных (WebSocket).
- Команды, разрабатывающие разные клиенты, хотят независимо менять свои BFF.
Когда не применять:
- Всего 1–2 внутренних сервиса и 1 тип клиента (gateway — лишняя сложность).
- Вы можете использовать готовый API gateway от облака (ALB, CloudFront) без своего кода.
6.2 Стили взаимодействия
| Стиль | Протокол | Связанность | Типичное применение |
|---|---|---|---|
| Синхронный RPC | REST, gRPC, Thrift | Высокая (клиент ждёт ответ) | CRUD, запрос-ответ, команды |
| Асинхронный Messaging | Kafka, RabbitMQ, NATS | Слабая (клиент не ждёт) | Фоновая обработка, интеграции |
| Event-Driven | Kafka, NATS, Pulsar | Очень слабая (издатель не знает подписчиков) | Событийные системы, CDC |
Описание: Синхронный RPC прост для понимания и отладки, но создаёт временную связанность — если сервис B упал, сервис A не может ответить. Асинхронный messaging разрывает связь: отправитель кладёт сообщение в очередь и продолжает работу. Event-driven — это частный случай messaging, где сервисы публикуют события (факты о том, что произошло), а подписчики реагируют независимо. Никто не знает о подписчиках заранее.
Ключевая идея: Выбор стиля — это компромисс между простотой (синхронность) и отказоустойчивостью (асинхронность).
Когда применять синхронный RPC:
- Запрос требует немедленного ответа (UI, API).
- Операция имеет низкую latency (< 100 мс).
- Вы контролируете обе стороны и готовы к версионированию.
Когда применять асинхронный messaging:
- Операция может быть выполнена в фоне (отправка email, генерация отчёта).
- Нужно выдержать пики нагрузки (очередь сглаживает).
- Потребитель может временно быть недоступен.
Когда применять event-driven:
- Несколько сервисов должны реагировать на одно и то же событие (заказ создан → биллинг, логистика, аналитика).
- Нужно слабое зацепление (можно добавить новый подписчик без изменения издателя).
- Строится CQRS или Event Sourcing.
6.3 Координация: оркестрация vs хореография
Описание: Оркестрация (orchestration) — центральный диспетчер (SagaOrchestrator) управляет последовательностью вызовов сервисов. Знает каждый шаг и компенсацию. Хореография (choreography) — сервисы общаются через события, без центра. Каждый сервис знает только, на какие события реагировать и какие публиковать. Оркестрация проще в отладке, но создаёт центральную точку отказа. Хореография более распределённая, но поток трудно восстановить.
Ключевая идея: Оркестрация — для предсказуемых, централизованных процессов. Хореография — для динамичных, легко расширяемых систем.
Когда применять оркестрацию:
- Процесс имеет 3–8 шагов, и логика компенсации сложная.
- Вы хотите видеть весь процесс в одном месте (легче отлаживать, логировать).
- Разные шаги принадлежат разным командам, но они не хотят знать о внутренних событиях друг друга.
- Нужен строгий порядок шагов.
Когда применять хореографию:
- 2–3 участника (больше — трудно понять поток).
- Каждый сервис сам знает, как компенсировать свои действия.
- Вы уже используете event bus для других задач.
- Команды, владеющие сервисами, предпочитают автономию и не хотят центрального координатора.
7. Паттерны работы с данными
7.1 Database per Service
Описание: Каждый микросервис владеет своей собственной БД. Другие сервисы не имеют прямого доступа к этой БД — только через API сервиса-владельца. БД могут быть разными: один сервис использует PostgreSQL, другой — MongoDB, третий — Redis. Это обеспечивает слабую связанность: изменение схемы БД одного сервиса не ломает другие. Однако усложняются распределённые транзакции и запросы, требующие данных из нескольких сервисов.
Ключевая идея: Физическая граница данных соответствует границе сервиса. Никто не лезет в чужую БД.
Когда применять:
- Вы переходите на микросервисную архитектуру.
- Разные сервисы имеют разные требования к БД (OLTP vs аналитика, SQL vs NoSQL).
- Команды хотят независимо развёртывать изменения схемы БД.
- Нужна изоляция отказов (падение БД одного сервиса не ломает другие).
Когда не применять:
- Данные критически требуют ACID-транзакций между сервисами.
- У вас модульный монолит — общая БД проще.
- Часто нужны JOIN-запросы между данными разных сервисов (придётся делать API composition).
7.2 CQRS
Описание: Command Query Responsibility Segregation — разделение модели записи (command) и модели чтения (query). Команды изменяют состояние через нормализованное хранилище (обычно ACID-база). Запросы читают из денормализованных (часто read-optimized) хранилищ, которые обновляются асинхронно через события. Позволяет масштабировать чтение и запись независимо, использовать разные модели для каждой стороны (например, для запросов — агрегаты и проекции). Усложняет систему: теперь есть eventual consistency.
Ключевая идея: Оптимизация для сценариев, где чтение и запись имеют кардинально разные требования.
Когда применять:
- Нагрузка на чтение на порядки выше, чем на запись (социальные сети, каталоги).
- Модели для чтения и записи сильно отличаются (запись требует нормализации, чтение — агрегатов).
- Нужно использовать разные технологии для чтения (Elasticsearch) и записи (PostgreSQL).
- Команда хочет внедрить Event Sourcing (CQRS хорошо сочетается).
Когда не применять:
- Традиционное CRUD приложение без высокой нагрузки.
- Strong consistency критична (user должен видеть свои изменения мгновенно).
- Команда не готова к eventual consistency и усложнению.
7.3 Event Sourcing
Описание: Вместо хранения текущего состояния хранится неизменяемая последовательность событий (event log). Каждое событие — это факт, который произошёл в системе (UserCreated, MoneyDeposited, MoneyWithdrawn). Текущее состояние вычисляется как проекция (projection) всей цепочки событий. Плюсы: полный аудит, возможность пересчитать состояние на любой момент времени, легкость введения новых проекций. Минусы: сложность с обновлением событий (их нельзя изменить), большой объём хранимых данных, eventual consistency.
| Событие | Данные |
|---|---|
| UserCreated | {id:1, name:"Маша"} |
| MoneyDeposited | {userId:1, amount:1000} |
| MoneyWithdrawn | {userId:1, amount:500} |
Текущий баланс = проекция событий (1000 - 500 = 500).
Ключевая идея: Время — это первоклассная сущность. Каждое изменение сохраняется навсегда.
Когда применять:
- Требуется полный аудит всех изменений (банки, логги, системы учёта).
- Нужно уметь «отматывать» состояние на любой момент времени (debug, аналитика).
- Вы уже используете CQRS (они хорошо сочетаются).
- События — естественная модель для предметной области (кейсы: корзина e-commerce, билетная система).
Когда не применять:
- Маленький проект без требований к аудиту (обычная БД проще).
- Требуется сильная консистенция и минимальная задержка чтения.
- Часто нужно обновлять существующие события (например, исправлять ошибки в уже сохранённых).
7.4 Транзакционные паттерны
| Паттерн | Суть |
|---|---|
| Transactional Outbox | В одной транзакции: запись в бизнес-таблицу + событие в outbox-таблицу |
| Transaction Log Tailing (CDC) | Debezium/Kafka Connect читает лог БД, публикует события |
| Polling Publisher | Периодический опрос outbox-таблицы (проще, но больше latency) |
| Saga | Цепочка локальных транзакций с компенсирующими действиями |
Описание: Transactional Outbox гарантирует, что событие будет опубликовано ровно один раз (at-least-once) атомарно с бизнес-изменением. Без этого паттерна вы рискуете: записали в БД, а отправка события провалилась → данные в БД есть, но другие сервисы не узнали. Outbox-таблица хранит события, а отдельный publisher (Polling или CDC) отправляет их в брокер.
Ключевая идея: Обеспечить надёжную публикацию событий без распределённых транзакций (2PC).
Когда применять (Transactional Outbox + CDC):
- Вы используете событийную архитектуру и не можете допустить потерю события.
- База данных умеет публиковать WAL (PostgreSQL logical replication, Debezium).
- Нужна низкая задержка публикации (CDC → Kafka с задержкой миллисекунды).
Когда применять (Polling Publisher):
- CDC слишком сложен для вашей инфраструктуры.
- Задержка в несколько секунд допустима.
- Вы используете БД без хорошей поддержки WAL (старые версии).
7.5 Репликация и шардирование
Типы репликации:
- Master-Slave (primary-replica): запись только в master, чтение — с master или slave.
- Master-Master (multi-primary): запись в оба узла, конфликты разрешаются приложением или БД.
Стратегии шардирования:
- Range-based (ключи 0-1000 → шард 1, 1001-2000 → шард 2) — просто, но возможен hot spot.
- Hash-based (
hash(key) % N) — равномерно распределяет, но сложно добавлять шарды. - Consistent Hashing — минимизирует перемещение данных при добавлении шардов.
- Directory-based — явная таблица маршрутизации.
Ключевая идея: Репликация — для отказоустойчивости и масштабирования чтения. Шардирование — для масштабирования записи и размера данных.
Когда применять репликацию (Master-Slave):
- Чтений намного больше, чем записей (10:1 и выше).
- Нужна высокая доступность: при падении master можно переключиться на slave.
- Допустима небольшая задержка репликации (асинхронная).
Когда применять шардирование:
- Данные не помещаются на один сервер (TB+).
- Запись не масштабируется через репликацию (master bottleneck).
- Есть естественный ключ шардирования (user_id, product_id).
8. Паттерны обнаружения сервисов
| Паттерн | Описание |
|---|---|
| Client-Side Discovery | Клиент опрашивает Service Registry (Eureka, Consul) и сам выбирает экземпляр |
| Server-Side Discovery | Балансировщик/gateway находит сервис через registry (K8s Service, AWS ALB) |
| Service Registry | БД живых экземпляров с health checks (Consul, etcd, ZooKeeper) |
| Self-Registration | Сервис сам регистрируется при старте (Eureka client) |
| 3rd Party Registration | Kubernetes регистрирует pod'ы через API Server |
Описание: В динамических средах (Kubernetes, облака) IP-адреса сервисов меняются постоянно. Service Discovery решает проблему «как клиенту найти адрес сервиса». Client-side discovery: клиент получает список адресов из registry и выбирает (например, ribbon → Eureka). Server-side discovery: клиент идёт на известный load balancer, который делает запрос в registry (K8s Service → Endpoints → Pods). 3rd Party Registration — когда оркестратор сам регистрирует контейнеры (K8s, Nomad).
Ключевая идея: Изоляция клиента от динамической природы инфраструктуры.
Когда применять Client-Side Discovery:
- Вы используете библиотеки вроде Netflix OSS, Consul API.
- Хотите тонкий контроль над балансировкой (retry, circuit breaker на стороне клиента).
- Сеть плоская и позволяет клиенту напрямую обращаться к сервисам.
Когда применять Server-Side Discovery:
- Вы используете Kubernetes (Service → ClusterIP/NodePort/LoadBalancer).
- Не хотите завязываться на конкретную библиотеку discovery в коде.
- Балансировщик уже есть и может выполнять health checks.
9. Паттерны отказоустойчивости
| Паттерн | Назначение |
|---|---|
| Circuit Breaker | Прерывание вызовов к аварийному сервису (состояния Closed → Open → Half-Open) |
| Retry | Повтор при временных ошибках (с экспоненциальной задержкой) |
| Timeouts | Ограничение ожидания ответа (не ждать вечно) |
| Bulkhead | Изоляция ресурсов (пулы потоков, отдельные соединения) |
| Rate Limiting | Token Bucket, Leaky Bucket — защита от перегрузки |
| Health Check | /health эндпоинт для оркестратора (liveness + readiness) |
| Graceful Degradation | Отдаём «урезанный» ответ вместо падения (например, кэш вместо БД) |
| Backpressure | Потребитель замедляет производителя (Reactive Streams, TCP window) |
Описание: Circuit Breaker оборачивает вызовы к удалённому сервису и отслеживает ошибки. При превышении порога ошибок переходит в состояние Open, и все вызовы немедленно возвращают ошибку (без реального вызова). Через таймаут переходит в Half-Open, пропускает пробный запрос. Если успешен — закрывается. Защищает систему от cascading failures.
Ключевая идея: Отказ одного сервиса не должен валить всю систему. Нужно быстро «отключать» проблемных зависимостей.
Когда применять Circuit Breaker:
- Вызовы к внешнему API или другому микросервису могут надолго зависать или падать с ошибками.
- Вы хотите избежать cascading failure (эффекта домино).
- У вас есть разумный таймаут для восстановления.
Когда применять Retry:
- Ошибки временные (network timeout, 503, ConnectionRefused).
- Запрос идемпотентен (повтор безопасен).
- Вы реализуете exponential backoff, чтобы не усугублять ситуацию.
Когда применять Bulkhead:
- Разные типы запросов к сервису (быстрые и медленные) не должны забирать общие ресурсы.
- Например, вызов /health не должен ждать очереди из медленных /report.
- Выделяем отдельные пулы потоков для критичных путей.
10. Паттерны кэширования
| Стратегия | Чтение | Запись | Описание |
|---|---|---|---|
| Cache-Aside | Приложение проверяет кэш, при промахе — загружает в БД и пишет в кэш | Приложение само обновляет кэш (инвалидация или прямой write) | Самая популярная, но требует кода в приложении |
| Read-Through | Кэш сам ходит в БД при промахе (прозрачно для приложения) | – | Прокси скрывает логику |
| Write-Through | – | Параллельно в кэш и БД (синхронно) | Гарантирует консистентность, но увеличивает latency записи |
| Write-Back (Write-Behind) | – | Сначала в кэш, потом асинхронно в БД | Очень быстрая запись, но риск потери данных при падении кэша |
| Refresh-Ahead | Предзагрузка данных до истечения TTL | – | Хорошо для предсказуемых паттернов доступа |
Инвалидация: TTL (время жизни), LRU/LFU (вытеснение по давности/частоте), ручная инвалидация по событию (CDC).
Ключевая идея: Кэш уменьшает latency и нагрузку на бэкенд, но добавляет сложность с консистентностью.
Когда применять Cache-Aside:
- Приложение уже написано, легко добавить проверку кэша.
- Вы контролируете как чтение, так и запись.
- Допустима eventual consistency.
Когда применять Read-Through/Write-Through:
- Не хотите, чтобы приложение знало о кэше.
- У вас уже есть прокси (например, Redis как cache proxy).
- Требуется строгая консистенция кэша и БД.
Когда применять Write-Back:
- Высокая интенсивность записи, а потеря нескольких секунд данных допустима (логи, счётчики).
- Бэкенд очень медленный или дорогой.
11. Паттерны балансировки нагрузки
| Алгоритм | Когда применять |
|---|---|
| Round Robin | Одинаковые серверы, примерно одинаковое время обработки запросов |
| Least Connections | Запросы разной длительности (одни задерживаются дольше других) |
| IP Hash (или Consistent Hash) | Нужны sticky sessions (сохранение сессии на одном сервере) |
| Weighted Round Robin | Серверы разной мощности (10% мощностей у одних, 90% — у других) |
| Least Response Time | Выбирается сервер с наименьшим средним временем ответа (с учётом pending запросов) |
Описание: Балансировщик распределяет входящий трафик между несколькими бэкендами. L4 балансировка работает на уровне TCP/UDP (IP + порт), быстрая, но не видит содержимого запроса. L7 (HTTP/gRPC) — видит заголовки, URI, может маршрутизировать по ним. Алгоритм выбирается исходя из природы нагрузки и требований к сессиям.
Ключевая идея: Спрятать множество бэкендов за одним IP/доменом и равномерно распределить нагрузку.
Когда применять Round Robin:
- Бэкенды идентичны по мощности и времени отклика.
- Нет требований к sticky sessions.
Когда применять Least Connections:
- Есть запросы, которые обрабатываются долго (например, загрузка файлов, streaming).
- Иначе Round Robin накопит длинную очередь на одном сервере.
Когда применять IP Hash:
- Сервис хранит сессию в памяти (in-memory session, локальный кэш).
- Клиент должен всегда попадать на один и тот же бэкенд.
12. Паттерны масштабирования и инфраструктуры
12.1 Масштабирование
- Вертикальное (scale up) — увеличение ресурсов одной машины (CPU, RAM). Предел: ~до 1000 RPS на одной машине. Просто, но имеет потолок.
- Горизонтальное (scale out) — добавление новых машин/контейнеров. Требует балансировки, репликации, шардирования. Не имеет теоретического предела.
Ключевая идея: Вертикальное — для первых лет проекта. Горизонтальное — когда упёрлись в потолок железа.
12.2 Инфраструктурные паттерны
| Паттерн | Суть |
|---|---|
| Microservice Chassis | Каркас (framework) с logging, health checks, config, метриками "из коробки" |
| Externalized Configuration | Конфигурация вне кода: Consul, Vault, ConfigMap, environment variables |
| Service Template | Шаблон кода для новых сервисов (сборка, деплой, observability) |
| Service Mesh | Istio, Linkerd – слой для трафика, безопасности, observability (обычно через sidecar) |
| Sidecar | Вспомогательный контейнер для cross-cutting функций |
| Ambassador | Прокси‑посредник для шардирования, экспериментов, ограничения частоты |
| Adapter | Стандартизирующий адаптер для логов, метрик, health‑check’ов |
Описание Service Mesh: Выделяет сетевые функции (retry, circuit breaker, mTLS, трассировка, метрики) в отдельный инфраструктурный слой. Каждый сервис получает sidecar-прокси (Envoy). Прокси управляют всем трафиком в/из сервиса. Разработчики не пишут код для этих функций.
Ключевая идея: Инфраструктурная сложность не должна загрязнять бизнес-код. Выносим её в отдельный слой.
Когда применять Service Mesh:
- У вас десятки микросервисов на разных языках.
- Требуется взаимный TLS (mTLS) между сервисами без изменения кода.
- Нужен глубокий мониторинг трафика (golden signals: latency, traffic, errors, saturation).
- Команда готова внедрить Istio/Linkerd и обучить разработчиков.
Когда не применять:
- 2–5 сервисов — overhead превышает пользу.
- Нет экспертизы в Kubernetes и sidecar-контейнерах.
- Разработчики уже реализовали resilience в коде (библиотеками).
13. Паттерны наблюдаемости (Observability)
| Паттерн | Инструмент | Назначение |
|---|---|---|
| Log Aggregation | ELK (Elasticsearch, Logstash, Kibana), Loki | Сбор, индексация и поиск логов |
| Application Metrics | Prometheus + Grafana | Сбор числовых метрик (RPS, latency, ошибки) |
| Distributed Tracing | Jaeger, Zipkin, OpenTelemetry | Отслеживание одного запроса через несколько сервисов |
| Audit Logging | Отдельное хранилище (S3, ClickHouse) | Кто, когда, что делал (безопасность, compliance) |
| Exception Tracking | Sentry, Rollbar | Агрегация и алертинг на ошибки |
| Health Check API | K8s probes (liveness, readiness, startup) | Автоматическое восстановление и маршрутизация трафика |
Описание: Наблюдаемость — это способность понять внутреннее состояние системы по её внешним выходам (логи, метрики, трейсы). Без наблюдаемости микросервисы превращаются в «чёрный ящик». Ключевые столпы: logs (структурированные события), metrics (числовые временные ряды), traces (цепочки вызовов). OpenTelemetry пытается унифицировать сбор всех трёх типов данных.
Ключевая идея: Вы не можете управлять тем, что не можете измерить. Наблюдаемость — предварительное условие для микросервисов.
Когда применять:
- У вас больше одного сервиса (нужны трассировка и агрегация логов).
- Вы переходим на микросервисы (обязательно внедрить до начала миграции).
- Есть SLO/SLA и нужно измерять их выполнение.
Когда отложить:
- Монолит с одним экземпляром (достаточно
journalctlиtop). - Проект на старте MVP (добавьте базовые метрики, но не ELK).
14. Паттерны безопасности
| Паттерн | Назначение |
|---|---|
| API Gateway Auth | Аутентификация и авторизация на gateway (JWT проверка, OAuth) |
| JWT / OAuth 2.0 | Токены доступа, передаваемые в заголовках между сервисами |
| Access Token (propagation) | Проверка токена при каждом межсервисном вызове (или передача микросервисам) |
| Anti-Corruption Layer (ACL) | Прослойка, изолирующая старую и новую модель (при миграции) |
| Secrets Management | HashiCorp Vault, AWS Secrets Manager, K8s Secrets |
| Zero Trust | Проверяется каждый запрос (нет «доверенной сети»), mTLS везде |
Описание: В распределённых системах безопасность сложнее, чем в монолите: сервисы общаются по сети (которую могут прослушивать). Zero Trust предполагает, что никому нельзя доверять по умолчанию. Каждый запрос аутентифицируется и авторизуется. JWT — самоодержимый токен, содержит права пользователя и подпись. Service Mesh может автоматически подписывать mTLS между сервисами.
Ключевая идея: Не полагайтесь на сетевые границы как на единственную защиту. Микросервисы — это распределённая система, и каждый вызов должен быть защищён.
Когда применять JWT токены:
- Нужно передать контекст пользователя (user ID, роли) через несколько сервисов без перепроверки в БД.
- Gateway проверяет подпись JWT и пробрасывает токен дальше.
Когда применять Anti-Corruption Layer:
- Вы мигрируете со старой монолитной системы на новую, и модели данных не совпадают.
- ACL переводит запросы из старого формата в новый и обратно.
15. Паттерны развёртывания и CI/CD
| Паттерн | Описание |
|---|---|
| Blue-Green | Два окружения (Blue и Green). Переключение балансировщика с Blue на Green — мгновенный rollback |
| Canary Release | Постепенный перенос трафика: 1% → 10% → 50% → 100% на новую версию |
| Rolling Update | Поочередное обновление pod'ов (K8s native) — 0 downtime, но опасность одновременных версий |
| Feature Toggle | Включение фич без деплоя (флаги в коде, конфигурации) |
| Dark Launch | Новая версия запущена в production, но не получает трафика (только для тестов) |
| Serverless | AWS Lambda, Cloud Functions — код как функция без управления серверами |
Описание: Blue-Green даёт мгновенный rollback, но требует вдвое больше ресурсов. Canary безопасен, но медленный и требует мониторинга (A/B тест). Rolling Update — стандарт K8s, экономный, но откат не мгновенный. Feature Toggle — самый гибкий: фича включена для 10% пользователей по email.
Ключевая идея: Развёртывание без простоя — обязательное требование для современных систем. Выберите паттерн, который соответствует вашему уровню риска и инфраструктуре.
Когда применять Blue-Green:
- Критичный сервис, где каждая минута простоя стоит больших денег.
- У вас есть лишние ресурсы (удвоенные мощности).
- Легко переключить балансировщик (например, AWS Route53 weighted records).
Когда применять Canary:
- Вы не уверены в новой версии (можно откатить до того, как ошибка затронет всех).
- Есть метрики и алертинг, чтобы автоматически остановить канарейку.
- Нужен A/B тест для бизнес-показателей.
16. Паттерны UI (Micro-Frontends)
- Server-Side Page Fragment Composition — бэкенд собирает HTML из фрагментов (например, Edge Side Includes).
- Client-Side UI Composition — браузер загружает и собирает компоненты разных команд (Web Components, Module Federation).
Описание: Аналог микросервисов на фронтенде. Каждая команда владеет своей частью UI (например, корзина, каталог, рекомендации). Эти части собираются вместе на сервере или в браузере. Позволяет разным командам независимо развёртывать свои фрагменты. Сложность — общий стиль, роутинг, состояние.
Ключевая идея: Если вы разбили бэкенд на микросервисы, а фронтенд остался монолитом — фронтенд-команда станет узким местом.
17. Паттерны рефакторинга и миграции на микросервисы
17.1 Strangler Fig («Удушающий инжир»)
Описание: Постепенная замена частей монолита на микросервисы. На первом этапе маршрутизатор направляет часть запросов к монолиту, часть — к новому сервису. Со временем монолит «сжимается», пока не останутся одни микросервисы. Аналогия с инжиром, который оплетает дерево-хозяина и в итоге его заменяет.
Ключевая идея: Мигрируйте постепенно, не переписывая всё сразу. Это снижает риск.
Когда применять:
- Вы осознали, что монолит больше нельзя развивать.
- Есть чёткие границы для первого сервиса (например, авторизация).
- Маршрутизатор (reverse proxy) позволяет направлять трафик по правилам (URI, заголовки).
17.2 Сателлитная архитектура
Описание: Монолит-ядро оставляется, а новые функции или высоконагруженные модули выносятся в отдельные сервисы (сателлиты). Монолит продолжает общаться с сателлитами через API. Это первый шаг к микросервисам без полной перестройки ядра.
Другие паттерны: Anti-Corruption Layer (ACL), Feature Toggle (для включения нового кода параллельно со старым).
18. Паттерны функций и событийной обработки (FaaS + Event-Driven)
18.1 Паттерн Decorator (функция‑декоратор)
Описание: Бессерверная функция (AWS Lambda, Cloud Function), которая прозрачно преобразует входящий запрос или исходящий ответ. Добавляет заголовки, проверяет права, добавляет значения по умолчанию, делает логгирование, валидацию. Вызывается перед основным сервисом и после него. Напоминает декоратор из ООП, но на уровне FaaS.
Ключевая идея: Расширение API без изменения основного сервиса, с автоматическим масштабированием.
Когда применять:
- Нужно добавить общую логику (логгирование, rate limiting) для нескольких эндпоинтов.
- Основной сервис — legacy или закрытый код (SaaS).
- Нагрузка непостоянная, и держать сервис ради декоратора накладно.
18.2 Событийно‑ориентированные конвейеры (Event‑Driven Pipeline)
Описание: Цепочка функций или микросервисов, связанных через event bus (Kafka, Pub/Sub). Каждый этап — отдельная функция/контейнер, которая реагирует на событие, обрабатывает его и публикует новое событие. Пайплайн легко расширять добавлением новых этапов. Подходит для асинхронной обработки, например: регистрация пользователя → запись в CRM → отправка письма → начисление бонусов.
Ключевая идея: Слабая связанность через события и параллельная обработка.
Когда применять:
- Обработка одного события требует нескольких независимых действий.
- Вы уже используете event bus для других задач.
- Не нужна строгая согласованность (eventual consistency допустима).
19. Системы на основе очередей задач (Work Queue)
19.1 Обобщённая очередь задач (Generic Work Queue)
Описание: Контейнер-источник (producer) публикует задания в очередь (RabbitMQ, Kafka, SQS). Множество контейнеров-исполнителей (workers) разбирают задания. Каждое задание обрабатывается только одним worker'ом (если не требуется broadcast). Очередь сглаживает пики нагрузки, позволяет масштабировать workers независимо от producer'а.
Ключевая идея: Разделение постановки задачи и её выполнения для асинхронной работы и масштабирования.
Когда применять:
- Выполнение задачи занимает время, и клиент не может ждать синхронно (обработка видео, генерация отчётов).
- Нагрузка неравномерная, и нужно выдержать пики.
- Задачи могут обрабатываться в любом порядке (или можно обойтись FIFO).
19.2 Multi‑Worker (разные типы исполнителей)
Описание: Разные типы исполнителей читают из одной очереди, но обрабатывают только задания определённого типа (по заголовку, полю type, routing key). Например, очередь задач на обработку изображений: worker для ресайза, worker для сжатия, worker для конвертации формата. Брокер (RabbitMQ) маршрутизирует задания в разные очереди, привязанные к разным workers.
Ключевая идея: Гибкость в типах обработки, сохраняя единый источник заданий.
20. Паттерны пакетной событийно‑ориентированной обработки (Event‑Driven Batch)
Канальные паттерны, преобразующие потоки событий.
| Паттерн | Описание | Диаграмма |
|---|---|---|
| Copier | Копирует событие в несколько выходных потоков для независимой параллельной обработки | src → Copier → out1, out2, out3 |
| Filter | Пропускает события, удовлетворяющие условию (например, amount > 1000) |
src → Filter → (true: out, false: discard) |
| Splitter | Разбивает одно составное событие на несколько простых | CompositeEvent → Splitter → Event1, Event2, Event3 |
| Sharder | Распределяет события по хэшу ключа в разные партиции (аналог шардирования) | События → Sharder (hash) → Part0, Part1, Part2 |
| Merger | Объединяет несколько потоков событий в один | in1, in2 → Merger → out |
Описание: Эти паттерны используются в потоковых движках (Apache Flink, Kafka Streams, Spark Streaming) для трансформации бесконечных потоков событий. Copier — для fan-out (разветвления). Filter — для селективной обработки. Splitter — для декомпозиции. Sharder — для распределения нагрузки по партициям. Merger — для слияния источников.
Ключевая идея: Событийные потоки требуют операторов, аналогичных операторам в функциональном программировании (map, filter, flatMap, partition, merge).
21. Координированные пакетные паттерны (Coordinated Batch)
21.1 Join (барьерная синхронизация)
Описание: Ожидает все необходимые события/результаты из нескольких источников, прежде чем продолжить обработку. Например: заказ должен дождаться подтверждения от платежей и от склада. Join-барьер собирает все части, и только когда все пришли — выдаёт объединённый пакет в следующий этап. Реализуется через stateful потоковую обработку (окна в Flink).
Ключевая идея: Координация разнородных событий, приходящих в разное время.
21.2 Reduce (агрегация)
Описание: Агрегирует набор событий в одно значение (сумма, гистограмма, среднее, max). Например, за 5-минутное окно собрать события кликов и посчитать их количество. Reduce часто используется вместе с оконными операторами (tumbling window, sliding window). В отличие от обычного агрегата, Reduce на потоке — это инкрементальное вычисление (не хранит все события, только текущее агрегированное значение).
22. AI-специфичные архитектурные паттерны (тренд 2025–2026)
| Паттерн | Описание |
|---|---|
| Agentic Loop | LLM-агент в цикле: думает (reason) → действует (act) → наблюдает (observe) → повторяет |
| ReAct | Reasoning + Acting — чередование "рассуждения" и "инструментов" |
| Plan-and-Execute | Умная модель (GPT-4) строит план, дешёвые модели выполняют шаги плана |
| Reflection | Агент проверяет и исправляет свой собственный output (self-critique) |
| RAG | Retrieval-Augmented Generation — сначала поиск по векторной БД, затем генерация ответа с найденным контекстом |
| Multi-Agent Collaboration | Несколько агентов с разными ролями (планировщик, исполнитель, критик, резюмер) |
Описание RAG: LLM не хранит все знания. При запросе сначала ищем в векторной БД (Embeddings) релевантные документы/чанки. Затем отправляем LLM промпт: «Вопрос: ... Контекст: ... Ответь на основе контекста». Это уменьшает галлюцинации и позволяет подключать актуальные данные.
Описание Agentic Loop: Агент получает задачу, разбивает на шаги, выполняет инструменты (API, поиск, калькулятор), анализирует результат и решает, достаточно ли, или нужны ещё шаги. Цикл продолжается, пока цель не достигнута или не превышен лимит шагов.
Ключевая идея: LLM — не просто генератор текста, а агент, который может использовать инструменты и рефлексировать.
Когда применять RAG:
- Нужно отвечать на вопросы по частной базе знаний (документы компании, FAQ, техподдержка).
- Модель не знает свежих данных (например, курс валют, новости).
- Хотите уменьшить галлюцинации.
Когда применять Agentic Loop:
- Задача требует многошагового планирования (найти отель → сравнить цены → забронировать).
- Нужно взаимодействие с внешними API (запрос к БД, отправка письма).
- Вы готовы к непредсказуемой задержке и стоимости (каждый шаг — вызов LLM).
23. Сводная матрица выбора
| Сценарий | Рекомендуемый паттерн(ы) |
|---|---|
| Стартап, скорость | Модульный монолит |
| Нужно добавить HTTPS/логирование в legacy | Sidecar |
| Требуется шардирование на уровне сервиса | Ambassador |
| Нормализация логов и метрик | Adapter |
| Простое горизонтальное масштабирование без состояния | Replicated Load‑Balanced Service |
| Распределённый кэш/поиск по ключу | Sharded Service |
| Параллельный поиск/агрегация | Scatter/Gather |
| Один экземпляр‑координатор | Leader Election + Lock/Lease |
| Разные клиенты (web, mobile) | BFF + API Gateway |
| Разные домены, большая команда | Микросервисы, Database per Service, Saga |
| Высокая нагрузка на чтение | Master-Slave + Cache-Aside (Redis) |
| Сложные отчёты + OLTP | CQRS |
| Полный аудит изменений | Event Sourcing |
| Асинхронная связанность | Event-Driven (Kafka), Choreography |
| Гарантированная публикация событий | Transactional Outbox + CDC |
| Распределённые транзакции | Saga (orchestration) |
| Отказоустойчивость | Circuit Breaker, Retry, Bulkhead |
| Обновление без downtime | Blue-Green, Canary |
| Бессерверное преобразование запросов | Decorator (FaaS) |
| Асинхронная обработка заданий | Generic Work Queue + Multi‑Worker |
| Разветвление и параллелизм в потоках событий | Copier, Splitter, Sharder |
| Фильтрация и объединение событий | Filter, Merger |
| Координация пакетной обработки | Join, Reduce |
| Миграция с монолита | Strangler Fig, ACL, Satellite |
| AI-агенты, работа с частной базой знаний | RAG, Agentic Loop |
| Инфраструктура как код | Sidecar, Adapter, Service Mesh |
Заключение
Выбор архитектурного паттерна — всегда компромисс между простотой, гибкостью и отказоустойчивостью. Основные правила:
- Начинайте с простого — модульный монолит решает 80% задач. Усложняйте только при появлении реальной боли.
- Чётко определяйте границы (bounded context) и владение данными (Database per Service).
- Автоматизируйте наблюдаемость и развёртывание до перехода к микросервисам — иначе вы ослепнете.
- Используйте метрики (RPS, latency, error budget) для обоснования изменений.
- Одноузловые паттерны (Sidecar, Ambassador, Adapter) позволяют добавлять инфраструктурные функции без модификации кода — не пренебрегайте ими.
- Пакетные и потоковые паттерны (Work Queue, Copier, Filter, Sharder, Reduce) образуют основу надёжных конвейеров обработки данных — изучайте Flink/Kafka Streams.
- AI-паттерны (RAG, Agentic Loop) — новая реальность. Начните с RAG для работы с документами, затем пробуйте агентов.
Данный справочник объединяет 80+ паттернов из классических и современных источников, предоставляя единый язык для архитекторов и разработчиков. Используйте его как шпаргалку при проектировании и рефакторинге систем.
Связанные статьи на сайте
- C4 Model: документируем архитектуру за 4 шага
- Модульный монолит или микросервисы: спектр решений
- ADR: как вести архитектурные решения
- Микросервисы vs монолит: когда что выбрать
- Event-Driven Architecture: основы
- Архитектурные роли в ИТ
- Принципы архитектора ПО
Что дальше
Кеширование: паттерны, стратегии, реализации — полный инженерный гайд: Cache-Aside, Read-Through, Write-Behind, Redis, HTTP-кеширование
System Design: как проектировать масштабируемые системы — фреймворк проектирования распределённых систем
Enterprise Architecture — архитектура предприятия и фреймворк TOGAF
Балансировщик нагрузки — L4 vs L7, Nginx, HAProxy
Связанные статьи: Архитектурные роли в ИТ: кто и на каком уровне применяет эти паттерны