Architecture Decision Record (ADR) -- короткий документ, фиксирующий одно архитектурное решение: что решили, почему, какие альтернативы рассматривали и какие последствия ожидаем.
Проблема без ADR
Через 6 месяцев:
─────────────────────────────────────────────────────
Новый разработчик: "Почему мы используем RabbitMQ,
а не Kafka?"
Сценарий 1 (без ADR):
Техлид: "Не помню точно... кажется, было обсуждение
в Slack... или на встрече... поищи в Confluence..."
Результат: Потеряны 2 дня на исследование.
Возможно, примут другое решение.
Сценарий 2 (с ADR):
Техлид: "Посмотри ADR-007 в репозитории."
ADR-007: Выбрали RabbitMQ из-за low latency для
routing задач, поддержки priority queues,
и отсутствия потребности в replay.
Результат: 5 минут на прочтение. Контекст понятен.
─────────────────────────────────────────────────────
Зачем нужны ADR
Проблема
Решение через ADR
"Почему так сделали?"
Документировано решение и причины
"Кто это решил?"
Указан автор и дата
"Какие были альтернативы?"
Описаны рассмотренные варианты
"Можно ли пересмотреть?"
Понятен контекст и ограничения
"Актуально ли это решение?"
Статус: accepted/deprecated/superseded
Знания уходят с людьми
Решения остаются в репозитории
Формат ADR
Классический формат (Michael Nygard)
# ADR-NNN: Заголовок решения
## Status
Accepted | Deprecated | Superseded by ADR-XXX
## Context
Что за ситуация? Какие силы действуют?
Технические, бизнесовые, организационные факторы.
## Decision
Что решили сделать.
## Consequences
Что хорошего и плохого из этого следует.
Расширенный формат
# ADR-NNN: Заголовок решения
## Status
Accepted
## Date
2026-02-22
## Authors
@username
## Context
Описание ситуации и проблемы.
## Decision Drivers
- Фактор 1
- Фактор 2
- Фактор 3
## Considered Options
1. Вариант A
2. Вариант B
3. Вариант C
## Decision
Выбранный вариант и обоснование.
## Consequences
### Positive
- Плюс 1
- Плюс 2
### Negative
- Минус 1
- Минус 2
### Risks
- Риск 1
## Links
- Related: ADR-005
- Supersedes: ADR-002
Пример ADR: Выбор базы данных
# ADR-003: Использование PostgreSQL как основной СУБД
## Status
Accepted
## Date
2026-01-15
## Context
Мы проектируем e-commerce платформу с требованиями:
- Транзакционная целостность для заказов и платежей
- Поддержка JSON для гибких атрибутов товаров
- Полнотекстовый поиск для каталога
- Масштабирование до 10M пользователей
- Команда имеет опыт работы с PostgreSQL
## Decision Drivers
- Надёжность транзакций (ACID)
- Гибкость структуры данных
- Опыт команды
- Стоимость владения
- Поддержка сообществом
## Considered Options
### 1. PostgreSQL
- ACID-транзакции
- JSONB для гибких схем
- Full-text search встроен
- Команда знает хорошо
### 2. MySQL
- ACID-транзакции
- JSON-поддержка слабее
- FTS через отдельные движки
- Проще в настройке
### 3. MongoDB
- Гибкая схема
- Нет полноценных транзакций (multi-document)
- Команда не имеет опыта
- Horizontal scaling из коробки
## Decision
Выбираем PostgreSQL, потому что:
1. Надёжные ACID-транзакции критичны для заказов и платежей
2. JSONB закрывает потребность в гибких атрибутах товаров
3. Встроенный FTS достаточен для начального этапа
4. Команда имеет 3+ года опыта с PostgreSQL
5. Расширяемость: pgvector для будущего ML-поиска
## Consequences
### Positive
- Надёжная транзакционная обработка заказов
- Один инструмент для structured + semi-structured данных
- Быстрый старт: команда знает технологию
- Экосистема: мониторинг, бэкапы, репликация
### Negative
- Вертикальное масштабирование как основная стратегия
- Шардинг сложнее, чем в MongoDB (Citus нужен)
- При >100M записей FTS может потребовать Elasticsearch
### Risks
- При взрывном росте может потребоваться шардинг
Mitigation: мониторинг производительности, план миграции
Пример ADR: Архитектурное решение
# ADR-007: Использование RabbitMQ для асинхронной обработки
## Status
Accepted
## Date
2026-02-10
## Context
Системе нужна асинхронная обработка для:
- Отправки email/SMS уведомлений
- Обработки загруженных изображений
- Синхронизации данных с внешними системами
Нагрузка: ~1000 msg/sec, задачи с приоритетами,
routing по типу задачи. Replay не требуется.
## Considered Options
### 1. RabbitMQ
- Зрелый, надёжный message broker
- Priority queues, routing, dead letter exchange
- Low latency (<1ms)
- Команда имеет опыт
### 2. Apache Kafka
- High throughput, event replay
- Лог-based storage
- Более сложная настройка
- Избыточен для наших задач
### 3. Redis Streams
- Простой, быстрый
- Не такой надёжный при сбоях
- Ограниченные возможности routing
## Decision
Выбираем RabbitMQ:
1. Priority queues для срочных уведомлений
2. Flexible routing через exchanges
3. Dead letter exchange для обработки ошибок
4. Replay не требуется (Kafka избыточен)
5. Команда знает RabbitMQ
## Consequences
### Positive
- Приоритизация задач из коробки
- Гибкий routing по типу задачи
- Простая обработка ошибок (DLX)
### Negative
- Нет event replay (если понадобится -- пересмотреть)
- Вертикальное масштабирование (для наших 1K msg/sec достаточно)
### Risks
- Если потребуется event sourcing → рассмотреть Kafka (ADR-XXX)
Когда создавать ADR
Нужен ADR
Решение
Пример
Выбор технологии
PostgreSQL vs MongoDB
Архитектурный паттерн
Monolith vs Microservices
Протокол интеграции
REST vs gRPC vs GraphQL
Стратегия деплоя
Kubernetes vs ECS
Подход к данным
Event Sourcing vs CRUD
Безопасность
Способ аутентификации
НЕ нужен ADR
Решение
Почему
Имя переменной
Слишком мелко
Выбор CSS-фреймворка
Легко заменить
Настройка линтера
Конфигурация, не архитектура
Формат логов
Операционное решение
Правило: ADR нужен если
┌──────────────────────────────────────────┐
│ Решение нужно документировать если: │
│ │
│ 1. Его трудно или дорого отменить │
│ 2. Оно влияет на несколько компонентов │
│ 3. Через 6 месяцев спросят "почему?" │
│ 4. Команда спорила о выборе │
│ 5. Есть несколько разумных альтернатив │
└──────────────────────────────────────────┘
Жизненный цикл ADR
Статусы
Draft ──▶ Proposed ──▶ Accepted ──▶ Deprecated
│ │
│ ▼
│ Superseded by ADR-XXX
│
└──▶ Rejected (с причиной)
Статус
Описание
Draft
Черновик, ещё обсуждается
Proposed
Предложен на ревью команде
Accepted
Принят, действует
Deprecated
Устарел, но не заменён
Superseded
Заменён новым ADR
Rejected
Отклонён (важно сохранить!)
Почему НЕ удалять отклонённые ADR
Отклонённый ADR ценен!
ADR-012: Переход на микросервисы (Status: Rejected)
Причина отклонения: команда из 4 человек, overhead не оправдан
Через год: команда выросла до 20 человек
→ Пересмотреть ADR-012, создать ADR-025 с новым контекстом
→ Не повторять исследование альтернатив с нуля